{"id":21071912,"url":"https://github.com/mfontanini/concave","last_synced_at":"2026-05-21T04:05:07.876Z","repository":{"id":69836942,"uuid":"478772537","full_name":"mfontanini/concave","owner":"mfontanini","description":"OCC-based key/value store","archived":false,"fork":false,"pushed_at":"2022-10-23T21:50:35.000Z","size":103,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-23T08:37:32.152Z","etag":null,"topics":["database","key-value"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mfontanini.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-04-07T00:37:20.000Z","updated_at":"2024-03-23T03:48:57.000Z","dependencies_parsed_at":"2023-03-10T11:00:57.283Z","dependency_job_id":null,"html_url":"https://github.com/mfontanini/concave","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mfontanini/concave","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mfontanini%2Fconcave","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mfontanini%2Fconcave/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mfontanini%2Fconcave/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mfontanini%2Fconcave/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mfontanini","download_url":"https://codeload.github.com/mfontanini/concave/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mfontanini%2Fconcave/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33288159,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-21T02:57:32.698Z","status":"ssl_error","status_checked_at":"2026-05-21T02:57:31.990Z","response_time":62,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","key-value"],"created_at":"2024-11-19T18:54:57.627Z","updated_at":"2026-05-21T04:05:07.861Z","avatar_url":"https://github.com/mfontanini.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# concave: (toy) OCC-based durable key/value store\n\n## What\n\nThis is a toy key/value store that allows 2 operations:\n\n* Read a key.\n* Atomically create/update a set of key/value pairs.\n\nKey/value pairs are versioned serially, and clients are required to send the latest version for each of the affected keys for a write to succeed. Therefore, the pattern for updating a key is:\n\n```\nlet version = get(key).version;\nwrite(key, value, version);\n```\n\nThis means:\n* Any writes that do not provide the latest/current version of the key/value pair will be rejected.\n* Any attempts to modify a key that is concurrently being written to by a separate put request will be rejected.\n* Any write operation only succeeds if none of the keys to be updated were found in the 2 states above. No partial\nupdates are made: writes either succeed and update all keys, or fail and their staged changes are rolled back.\n\n## Durability\n\nWrite requests are asynchronously batched together and flushed to disk periodically using a write ahead log. Put requests wait for the associated write to be flushed to disk before returning, which means requests will not return until data is considered to be persisted successfully on disk.\n\nBincode is used as the serialization format for objects in the log.\n\n### Compaction\n\nLog files are periodically compacted together, persisting only the latest version for a key and dropping the stale ones.\n\n## API\n\nAn HTTP API is exposed that allows the 2 operations;\n\n### /v1/get?key=\u003ckey\u003e\n\nReturns the state of the key or replies with 404 if it's not found.\n\n**Response (JSON)**\n```\n{\n    \"key\": \"\u003ckey\u003e\",\n    \"value\": \u003cvalue\u003e,\n    \"version\": \u003cversion\u003e,\n}\n```\n\nNote that values can be any of:\n\n* String\n* Integer\n* Float\n* Bool\n* Array of numbers\n\n### /v1/put\n\nAttempts to modify a set of key/value pairs.\n\n**Request body (JSON)**\n\n```\n[\n    {\n        \"key\": \"\u003ckey\u003e\",\n        \"value\": \"\u003cvalue\u003e\",\n        \"version\": expected_version,\n    },\n    ...\n]\n```\n\n\n**Response (JSON)**\n```\n{\n    \"result\": \"Success\" | \"Failure\",\n    \"error\": \"\u003cerror message\u003e\", # only set on Failure\n}\n```\n\n## Benchmarks\n\nA few random benchmarks, all ran using the `cli` example app. These were ran on an Intel i7-9750H @ 2.6GHz,\n32 GB of RAM writing to an SSD. All benchmarks use UUID as keys and value unless otherwise specified.\n\nThe configuration used when running the server are the once in the sample config file:\n* 5 ms batch time.\n* 8kb batch size.\n* 4MB block size.\n* 10 max blocks.\n\nThe results are:\n\n* 512 parallel tasks each doing 1000 gets for non existent keys: 148k gets/s.\n* 512 parallel tasks inserting 500 batches of 1 object each: 70k insertions/s.\n* 512 parallel tasks inserting 5 batches of 500 objects each: 264k insertions/s.\n* 512 parallel tasks fetching and incrementing a single key that maps to a number, each doing 1000\niterations: 43k increments/s. This is basically a `put(get(key) + 1)` 1000 times per task. This is likely a\nmore meaningful benchmark as it tests contention between reads and writes.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmfontanini%2Fconcave","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmfontanini%2Fconcave","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmfontanini%2Fconcave/lists"}