roadmap
Where giong is going
Milestones in order, with no dates: a milestone is done when its exit criteria are met.
Goal
A runtime for network services on Linux that makes the fewest possible system calls and keeps tail latency low, by committing fully to io_uring and to one thread per core.
By 1.0, a team can write and deploy a real REST API (Postgres or MySQL, Redis, calls to other HTTPS services, HTTPS itself) with giong's crates alone, in an ordinary Docker or Kubernetes setup. Each crate that replaces a Tokio-based one is measured against it with a reproducible benchmark (tokio-postgres with deadpool, mysql_async and SQLx, redis-rs, reqwest, axum), and the README says where giong does not win.
Agent-first
More and more code is written by AI agents, so giong is built for them to use correctly on the first try and to fix on their own when they get something wrong. That means removing vague conveniences and implicit defaults, never safety: the faster code is written, the tighter the checks around it have to be.
- Errors explain themselves. Every error giong raises carries a stable code (
GIONG-E0001…), says what went wrong and how to fix it, and links to a page about it. Functions keep returningio::Error;giong::error::code(&err)lets code, and agents, match on the code instead of the message. - One obvious, correct way. No macros and no magic. Types strict enough that a mistake is a compile error: enums instead of flags and strings,
Durationinstead of a number of milliseconds,#[must_use]on futures and handles. No implicit defaults: every timeout and size limit is finite, documented, and visible inDebugoutput. - Verification is the law. Tests, cancellation tests, ThreadSanitizer,
loom, fuzzing and soak tests run in CI and block merging;cargo-semver-checksguards the API. Machines check the work, so human review is not the bottleneck. - Documentation machines can read.
AGENTS.mdin the repository;llms.txtandllms-full.txton giong.run, generated from the docs; a runnable example for every public API. Doctests are the source of truth. - Observable from the inside. Per-worker statistics, connection-pool statistics and per-route latency, and structured logs as JSON lines. The runtime adds no dependency for this;
tracingis an optional feature. - An MCP server,
giong-mcp. Attached to a running service, it lets an agent read the state of workers, tasks, connections, pools, statistics and profiles. Read-only, listening on localhost or a Unix socket, and only when the service turns it on.
- 0.1done
Foundation
Executor, io_uring driver, TCP, UDP, files, timers, thread-per-core runtime, busy-poll mode, cross-thread channel, cancellation safety, backpressure, tests and benchmarks. See CHANGELOG.md.
- 0.2done12 of 12
A runtime you can serve from
0.2 took the pieces a real service needs first, wherever they stood in the earlier plan, together with the verification that needed no extra hardware.
- Graceful connection draining on shutdown (
Builder::shutdown_grace). - Unix domain sockets.
- Multishot receive for UDP.
- More file operations: metadata, rename, remove, directories.
giong-http: an HTTP/1.1 server library grown out of the example.- TLS through
rustls(giong-tls, server side), and HTTPS ingiong-http. - Run the multi-threaded tests under ThreadSanitizer (nightly), locally and in CI.
- Verify the declared minimum Rust version in CI (1.80, libraries).
- Exercise the ring setup fallbacks by forcing them on a new kernel (
GIONG_RING_TIER). - Compare against Monoio and Glommio on one core over loopback (see the README).
- A first two-core measurement (the load generator is the limit; see the README).
- Fuzz-style tests for the HTTP parser: 500,000 random inputs for the request parser and the chunked decoder in
giong-http.
- Graceful connection draining on shutdown (
- 0.3done8 of 8
Prove it
The numbers so far come from a 4-vCPU virtual machine over loopback. Before adding more features, find out what is actually true.
- Benchmark on a multi-core machine: 1 to 10 workers on a 14-core i5-13500 under WSL2, over loopback (see the README). The load generator on a separate host and a physical network card move to 0.4.
- Measure throughput from 1 to N workers with
bench/workers.sh. Under WSL2 the one-worker baseline is unreliable, so scaling efficiency still needs bare metal (0.4). - Repeat the Monoio and Glommio comparison on several cores (same run). On a physical network: 0.4.
- Run the test suite on real 6.0 and 6.1 kernels (in QEMU, in CI; it found that 6.0 could fail to start a runtime, now fixed).
- Model-check the cross-thread wake-up handshake with
loom(it found a lost wake-up, now fixed). - Coverage-guided fuzzing (
cargo fuzz) of thegiong-httpparser, the chunked decoder and a whole connection, nightly in CI. - Add a soak test: hours of connection churn with fd and memory checks (two hours every night in CI).
- A security review of
giong-tlsand the crates that use it (report; it found and fixed two medium issues). It was done by the project's AI agent: a review by an outside person is still wanted before anyone relies ongiong-tlsfor something that matters.
Done when: published multi-core results with their method, and no open memory- or thread-safety finding.
- 0.4current10 of 11
Foundations for services
What every client library and service needs before the database and web crates can be built on it. Worked on alongside 0.3; changes to the runtime's wake-up path wait for 0.3's.
- Carried over from 0.3: run
bench/workers.shon bare-metal Linux with the load generator on a second machine over a physical network card, for scaling efficiency and the Monoio and Glommio comparison on a real network. - Asynchronous DNS resolution (
/etc/hosts,resolv.conf, UDP then TCP, a cache per worker), andTcpStream::connectby name, trying addresses the RFC 8305 way. - The client side of
giong-tls: the machine's CA certificates or compiled-in ones, ALPN, client certificates. - A bounded channel and a oneshot channel in
sync. spawn_onthat returns a handle to the spawned task's result.giong-http: the client's address inRequest, and a limit on open connections.- Vectored writes (
writev) so a response head and body need no copy. - A clear error when io_uring is blocked, and a guide to allowing it in Docker and Kubernetes until the epoll driver exists.
- Remaining file operations: reading directories,
fallocate. - Agent-first groundwork: error codes with their documentation pages and
giong::error::code,AGENTS.md,llms.txt. - Load balancing across workers without moving running tasks:
Handle::spawn_balanced(jobs wait in a shared queue for the first idle worker),TcpListener::bind_balanced(a busy worker hands new connections to a less busy one) andHandle::least_loaded_worker.
Done when: every item above with tests, including cancellation tests for each new operation.
- Carried over from 0.3: run
- cratesdone5 of 5
giong-postgres 0.1
A new crate: the Postgres v3 protocol on giong.
- Connecting, SCRAM-SHA-256 (with
ring, already a dependency through rustls), TLS. - Parameterised queries, prepared statements with a cache, transactions, the common data types.
- Pipelining by default: queries from many requests on one core share one write.
- A connection pool per core, with no
ArcorMutexbetween threads. - Per-worker and per-pool statistics as a public API, in
giongand here.
Done when: the test suite passes against real Postgres 14 to 17 in CI, the protocol parser is fuzzed, and a benchmark compares it with tokio-postgres and deadpool.
- Connecting, SCRAM-SHA-256 (with
- cratesdone3 of 3
giong-mysql 0.1
A new crate: the MySQL client/server protocol on giong, with the same shape as giong-postgres.
- Connecting over TCP or a Unix socket, TLS,
caching_sha2_password(including the RSA exchange) andmysql_native_password. - Prepared statements with a cache and the binary protocol, transactions, the common data types.
- Pipelining by default, and a connection pool per core.
Done when: the test suite passes against real MySQL 8.0, 8.4 and 9 in CI, the packet parsers are fuzzed, and a benchmark compares it with mysql_async and SQLx.
- Connecting over TCP or a Unix socket, TLS,
- cratesdone4 of 4
HTTP client and giong-redis 0.1
- An HTTP/1.1 client in
giong-http(featureclient): keep-alive, a pool per host, HTTPS, timeouts, redirects. Benchmarked against reqwest (bench/http-client.sh). - What production traffic needs from it: HTTP proxies (
HTTPS_PROXY,NO_PROXY,CONNECTtunnels), gzip and deflate bodies with the limit on what they expand to, and bodies streamed piece by piece. - The database and client parsers fuzzed (
*/fuzz/), and the database crates tested against PostgreSQL 14 to 17, MySQL 8.0, 8.4 and 9.1, Redis 6.2 to 7.4 and Valkey 8 in CI. giong-redis, a new crate: RESP3, automatic pipelining, a pool per core, pub/sub. Benchmarked against redis-rs and fred (bench/redis.sh). RESP2-only servers (Redis 5 and older) are not supported: RESP3 has been in every Redis since 6.0 (2020).
Done when: the client fetches from a public HTTPS API,
giong-redispasses against a real Redis 7 in CI, and benchmarks compare them with reqwest and redis-rs. - An HTTP/1.1 client in
- cratescurrent1 of 4
giong-web 0.1 and giong-mcp 0.1
- Streaming request and response bodies in
giong-http. giong-web, a new crate: a router with path parameters, middleware (logging, timeouts, CORS, request ids, compression), JSON throughserdebehind a feature. Errors are problem+json bodies with giong codes (GIONG-E1201toE1213). Benchmarked against axum (bench/web.sh).- Structured logs as JSON lines, and an optional
tracingfeature. The JSON lines are done (giong_web::middleware::Logger);tracingis not. giong-mcp, a new crate: the MCP server described under Agent-first.
Done when: a complete example REST API (CRUD on Postgres, a Redis cache, HTTPS) in the repository, and a benchmark of it against the same API on axum.
- Streaming request and response bodies in
- 0.5planned0 of 1
Runs where io_uring is blocked
Starts once 0.3 is done, because both change the driver and the wake-up path.
- An epoll driver, chosen automatically when io_uring cannot be set up, or by an environment variable. The worker still blocks in one place that a wake-up from another thread can interrupt.
Done when: the whole test suite passes on both drivers, giong runs in Docker with the default seccomp profile, and the difference in performance is measured and published.
- 0.6planned0 of 3
HTTP/2 and adapters
- HTTP/2 in
giong-http, over TLS with ALPN. - Adapters for the
futures-io/ Tokio I/O traits, so protocol crates that are generic over the transport can run on giong. - Decide, based on demand, whether a hyper integration is worth maintaining.
Done when: an HTTPS server serving real browsers over HTTP/2, and
h2specpassing. - HTTP/2 in
- 0.7planned0 of 6
Speed
Each item lands only with a benchmark showing what it buys.
- Registered ring fd and fixed files (direct descriptors) to skip fd lookups.
- Zero-copy send for large responses.
- Receive bundles (several buffers per completion).
- Optional
SQPOLLmode. - Optional NAPI busy polling.
- Kernel TLS (kTLS) for
giong-tls.
Done when: a documented, reproducible gain for every option that is merged.
- 1.0planned
Stable
A stable API. Requires: a review of every public item against the Agent-first principles,
cargo-semver-checksin CI, every public item documented, the limitations section of the README reduced to deliberate non-goals, and at least one production user reporting back.WebSocket and gRPC come later, when someone needs them.
Deliberate non-goals
These are deliberate. Proposals that need them will be declined.
- Production on other operating systems. Linux is the only platform giong is tuned and measured on, and io_uring stays the main path. A Linux epoll driver is planned (0.5) for machines where io_uring is blocked, such as Docker's default seccomp profile. Running on macOS for development (kqueue) may follow it; Windows (IOCP) not before 1.0, and only if users need it.
- Work stealing. A task that has started stays on its worker, so tasks need not be
Send. Balancing happens where new work starts:Handle::spawn_balancedandTcpListener::bind_balanced. - Every workload. giong covers network services: HTTP, databases, caches and the clients they need. It does not try to replace Tokio for everything Tokio is used for.
Sendfutures as a requirement. The API stays usable withRcandRefCell.- Macros that hide control flow, and unbounded defaults. See Agent-first.