Kinto/kinto: a self-hosted JSON store with sync and sharing
A generic JSON document store with sharing and synchronisation capabilities.
At a glance
- What is it?
- Kinto is a minimalist JSON storage service built on Pyramid that adds versioning, permissions and sharing to a plain document store. It targets teams that need a small HTTP API for syncing client data without adopting a full backend platform.
- Who is it for?
- Adopt Kinto if you want a small, self-hosted HTTP store for client-side records and you are willing to run PostgreSQL. Do not adopt it for full-text search, relational queries or analytics.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 2, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem Kinto solves for client-heavy applications
Kinto describes itself as a minimalist JSON storage service with synchronisation and sharing abilities. That sentence is the whole product scope. The target is an application that keeps records on a client (a browser, a mobile app, a desktop tool) and needs somewhere to put them, with the ability to sync changes between devices and to decide who else can read or write a given set of records. Building that from scratch means writing a versioned REST API, a conflict story, an access-control layer and a change feed. Kinto ships all four as a service.
It is not a general-purpose database and it does not try to be. There are no joins, no aggregations and no query planner to reason about. Records live inside collections, collections live inside buckets, and every record is addressed by an HTTP path. If your application mostly reads and writes whole documents that belong to a user or a group, the shape fits. If your application needs to ask questions across millions of rows, it does not.
Buckets, collections and records: the data model behind the API
The hierarchy is the API. A bucket is the top-level container and the unit that permissions are usually attached to. A collection sits inside a bucket and groups records of the same kind. A record is a JSON object with an id, and it is the thing clients actually sync. Each level is reachable over HTTP, so a record's address is a nested path rather than a query.
Because records are versioned, a client can send the version it last saw and the server can reject a write that would overwrite a newer one. That is what makes the sync story workable on flaky connections: the client does not have to trust its own copy. The sharing story sits in the same layer. Permissions are evaluated per object, so a bucket or collection can be readable by one principal and writable by another without a separate authorization service.
The backends are pluggable. The README lists in-memory storage for development and PostgreSQL 9.5+ for production, and the docker-compose file wires PostgreSQL for storage and permissions plus memcached for the cache. Those three roles (storage, permission, cache) are configured independently through KINTO_STORAGE_BACKEND, KINTO_PERMISSION_BACKEND and KINTO_CACHE_BACKEND, which is the main architectural decision you make at deploy time.
Installing Kinto and making a first request
The repository ships a Dockerfile and a docker-compose.yml, and the compose file is the shortest path to a running server. It starts PostgreSQL 14 with a healthcheck, a memcached instance, and the web service on port 8888, with the backend environment variables already set.
docker compose upOnce the web container reports that it is listening, the API is reachable at http://localhost:8888/v1/. The Dockerfile's default command runs migrations before starting the server, so a fresh database is prepared on first boot.
For a local install without Docker, the Makefile drives uv. The install target syncs dependencies, and install-postgres adds the PostgreSQL extra. The server configuration is generated by kinto init, which the Makefile writes to config/kinto.ini.
make install-postgres
.venv/bin/kinto init --ini config/kinto.ini --backend=postgresql
make serveThe make serve target depends on install-dev, the generated config, a migrate step and a version.json file, so it is the target to use while developing rather than a bare kinto start. If you only want to see the service come up, the Dockerfile's own default config uses the memory backend, which is why the image can start without a database.
Where Kinto stops being the right tool
The most obvious limit is query capability. Kinto stores JSON documents and returns them; the README and the repository layout describe storage, sync and sharing, not search or aggregation. If you need full-text search, faceted filtering or analytical queries, you will end up exporting records somewhere else, and at that point the store is a staging area rather than a system of record.
The second limit is operational. The production path assumes PostgreSQL and, in the compose setup, memcached. That is a real deployment to run: a database to back up, a cache to monitor, migrations to apply on upgrade. The in-memory backend is explicitly for development, so it is not a way to avoid that work.
Third, the permission model is object-level, not row-level in the SQL sense. Sharing works by attaching permissions to buckets and collections, which is a good fit for team or user boundaries and a poor fit for rules that depend on the contents of a record. If your access rules are computed from fields inside the document, you will be enforcing them in your application anyway.
Finally, the licence metadata is worth reading directly. The repository's LICENSE file is the source of truth; the classifier in pyproject.toml says Apache Software License, and the packaging metadata given here reports the licence as NOASSERTION. That discrepancy is not a reason to avoid the project, but it is a reason to open LICENSE before you ship.
Kinto compared with running your own REST layer on Postgres
The honest alternative is not another product, it is a thin REST service you write yourself on top of PostgreSQL or SQLite. The difference is what you get for free. A hand-rolled service gives you full control over the schema and lets you write any query you like. Kinto gives you a fixed document model and in exchange hands you versioning, a change feed for sync, and object-level permissions without you designing them.
That trade is worth naming precisely. With your own service, adding a new field or a new index is a migration you control. With Kinto, the record is opaque JSON, so new fields need no migration at all, but you also cannot index them the way you would a column. Teams that already have a Postgres schema and a query-heavy product will find Kinto constrains them. Teams whose hard problem is keeping many clients in sync with correct permissions will find that Kinto has already solved the part they were dreading.
A second, narrower alternative is to keep the data on the client and use a hosted backend-as-a-service. That removes the PostgreSQL and memcached operations entirely, at the cost of the self-hosting property that the project's own description puts in the name of its PyPI summary: Store, Sync, Share, and Self-Host.
Maintenance, releases and upgrade cost
The project is not archived, and the last push was on 2026-09-19. Recent releases are 26.3.1, 26.3.2 and 26.3.3, dated 2026-07-01, 2026-07-02 and 2026-08-10 respectively, so the release cadence in that window is steady rather than dormant.
The upgrade cost is dominated by the database, not the Python package. The Dockerfile's default command runs kinto migrate before kinto start, which tells you migrations are part of the normal boot path and therefore part of every upgrade. Back up PostgreSQL before pulling a new image, and read CHANGELOG.rst rather than assuming a patch release is inert.
There is one dependency detail worth flagging. The pyproject.toml pins setuptools<82 with a comment explaining that Pyramid still imports pkg_resources, and that without the upper bound the resolver downgrades Pyramid to 2.0.2 and imports fail. That is the kind of constraint that bites when you build your own image or vendor the dependencies instead of using the published one. Python 3.10 or newer is required, and the Dockerfile builds on python:3.10-bullseye.
On licensing, the classifier in pyproject.toml names the Apache Software License while the packaging metadata reports NOASSERTION. Both are visible in the same repository, so the LICENSE file is what you should read and, if it matters to your organisation, what your legal team should review. Nothing here is legal advice.
Editorial conclusion
Adopt Kinto if you want a small, self-hosted HTTP store for client-side records and you are willing to run PostgreSQL. Do not adopt it for full-text search, relational queries or analytics. Verify first that the permission model fits your sharing rules, that the storage backend you need is supported, and that the version pinned in your image still matches the API your clients expect.
Frequently asked questions
How do I install Kinto/kinto?
The repository provides a docker-compose.yml that starts PostgreSQL, memcached and the web service on port 8888, so docker compose up is the shortest path. For a local install the Makefile uses uv, with make install-postgres for the PostgreSQL extra and kinto init to generate config/kinto.ini.
How do I use Kinto/kinto?
You use it over HTTP: records are JSON documents addressed by path inside collections, and collections live inside buckets. The README points to a first-steps tutorial in the online documentation, and clients sync by sending the version of a record they last saw so the server can reject stale writes.
What Python version and backends does Kinto/kinto require?
The README lists Python 3.10 or newer, with in-memory storage for development and PostgreSQL 9.5 or newer for production. The Dockerfile builds on python:3.10-bullseye and syncs the postgresql, memcached, redis, monitoring and container extras.
What licence is Kinto/kinto released under?
The classifier in pyproject.toml says Apache Software License, while the packaging metadata given for the repository reports the licence as NOASSERTION. The LICENSE file in the repository is the authoritative source and should be read directly.
Does Kinto/kinto support full-text search or SQL-style queries?
The README describes Kinto as a minimalist JSON storage service with synchronisation and sharing abilities, and the repository layout shows storage, permission and cache backends rather than a query engine. Records are retrieved as documents, so search and aggregation are not part of the documented scope.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/kinto-kinto)