Kinto / Kinto/kinto

Performance for plural endpoints is suboptimal

Open
#3,157 0 comments 0 reactions 0 assignees View on GitHub
stale
Dominant language
Python
Stars
4.4k
Forks
437
Avg merge
1d 2h
Merged PRs (30d)
15

Description

Some background: we use Kinto as a synced per-user data store, using a bucket per app deployment/environment, and a collection per user. Users can often have thousands of records (most fairly small, a handful per collection fairly large).

We're using `postgresql` for the `storage` and `permission` backends (and `memcached` for the `cache` backend).

The performance of plural endpoints (e.g. `/v1/buckets/my-app-staging/collections/my-user/records` to get all records in a collection) in the current server implementation is a bit disappointing (ignoring caching).

I've profiled the Kinto server using Sentry, by adding `traces_sample_rate=1.0, _experiments={"profiles_sample_rate": 1.0}` to the `sentry_sdk.init()` call. While the SQL queries themselves take a bit of time, it's also spending a considerable amount of time in library functions.

## JSON deserialisation

Swapping out [`json.loads`](https://docs.python.org/3.8/library/json.html#json.loads) for [`msgspec.json.decode`](https://jcristharif.com/msgspec/api.html#msgspec.msgpack.decode) for SQLAlchemy's JSON deserialisation gives a substantial improvement:

```
Benchmark (json.loads): curl http://localhost:8888/v1/buckets/my-app-development/collections/my-user/records
Time (mean ± σ): 1.490 s ± 0.114 s [User: 0.006 s, System: 0.008 s]
Range (min … max): 1.327 s … 1.879 s 100 runs
```

```
Benchmark (msgspec.json.decode): curl http://localhost:8888/v1/buckets/my-app-development/collections/my-user/records
Time (mean ± σ): 1.267 s ± 0.052 s [User: 0.006 s, System: 0.007 s]
Range (min … max): 1.150 s … 1.428 s 100 runs
```

This improved the performance by ~18% for this collection (~3000 records).

Contributor guide

Open the contributing guide

Research direction

Start at the plural records endpoint and SQLAlchemy's JSON deserialization path, then reproduce the reported benchmark for a collection of about 3,000 records. Compare json.loads with msgspec.json.decode and profile the remaining query and library costs. Done means the endpoint's performance is measurably improved without changing its response behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
memcached, postgresql, python
Domain
api, backend, databases, performance
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.