giong

docs

Get started with giong

Requirements, a first server, and where everything else is documented. The API reference for each crate is on docs.rs.

Requirements

kernel
Linux 6.0 or newer, 6.1+ recommended. Developed and tested on 6.18.
rust
1.80 or newer for the libraries.
elsewhere
giong does not build on Windows or macOS. Use WSL2 with a 6.x kernel or a Linux virtual machine.
docker
Docker's default seccomp profile blocks io_uring. docs/DEPLOYMENT.md shows how to allow it in Docker, Compose and Kubernetes without turning seccomp off.
license
MIT OR Apache-2.0, at your option.

Install

The crates are on crates.io. Add the runtime and the layers you need; giong-http takes --features tls for HTTPS and --features client for its client.

cargo add giong
cargo add giong-http          # or giong-web for routing, middleware and JSON

A first server

Put this in src/main.rs. Every worker binds its own SO_REUSEPORT listener on the same port, and the kernel spreads connections across cores.

use std::time::Duration;
use giong::net::TcpListener;
use giong_http::{Request, Response, Server};

async fn handler(req: Request) -> Response {
    match (req.method(), req.path()) {
        ("GET", "/health") => Response::text("ok"),
        ("POST", "/echo") => Response::new(200).body(req.body().to_vec()),
        _ => Response::new(404),
    }
}

fn main() -> std::io::Result<()> {
    giong::Builder::new()
        .shutdown_on_signals(true)                  // Ctrl-C / SIGTERM stop it gracefully
        .shutdown_grace(Duration::from_secs(10))    // requests in progress are answered
        .build()?
        .run(|_worker| async {
            let listener = TcpListener::bind("0.0.0.0:8080").expect("bind");
            Server::new().serve(listener, handler).await;
        })
}

Then run it:

cargo run --release          # listens on port 8080
curl localhost:8080/health   # ok

Examples

Each one runs from a clone of the repository; the crates' READMEs have more. examples/

examples/echo.rs

A TCP echo server on every core.

cargo run --release --example echo
nc 127.0.0.1 7000

examples/http.rs

A small HTTP/1.1 server: keep-alive, pipelining, idle timeouts, a header size limit and graceful shutdown on SIGINT and SIGTERM. The same routes the benchmarks use.

cargo run --release --example http
curl localhost:3006/json

examples/udp_echo.rs

A UDP echo server, receiving with multishot recvmsg.

cargo run --release --example udp_echo
echo hello | nc -u -w1 127.0.0.1 7001

examples/cat.rs

Prints files to standard output, reading them through io_uring with positional reads.

cargo run --release --example cat -- Cargo.toml

API reference

Every public item is documented, with an example where it helps.

Error codes

Every error giong raises starts with a code, says what went wrong and how to fix it, and links to its page. 81 codes so far. Match on giong::error::code(&err), never on the message.

GIONG-E0102: no address found for db.internal. Fix: check the spelling of the name,
/etc/hosts, and the DNS servers in /etc/resolv.conf (in a container, the network it is
attached to). See https://github.com/giong-run/Giong/blob/main/docs/errors/E0102.md
The runtime8 codes
GIONG-E0001IoUringUnavailableio_uring is not available
GIONG-E0002KernelTooOldthe kernel is too old
GIONG-E0003SignalsTakenanother runtime handles the signals
GIONG-E0004InvalidConfiginvalid runtime setting
GIONG-E0005Unexpectedunexpected result from the kernel
GIONG-E0006MixedReadsread used after recv
GIONG-E0007TimedOutthe time limit passed
GIONG-E0008NoSuchWorkerno such worker
Network and name resolution8 codes
GIONG-E0100InvalidAddressinvalid address
GIONG-E0101InvalidHostNameinvalid host name
GIONG-E0102HostNotFoundhost not found
GIONG-E0103NoAddressesno address to use
GIONG-E0104NoDnsServerno DNS server configured
GIONG-E0105DnsTimeoutDNS server did not answer
GIONG-E0106DnsServerFailureDNS server failed
GIONG-E0107DnsBadResponsemalformed DNS answer
Files1 codes
GIONG-E0200InvalidPathinvalid path
giong-http (its client)10 codes
GIONG-E1101HttpClientRequestinvalid HTTP request
GIONG-E1102HttpClientConnectcannot connect to the HTTP server
GIONG-E1103HttpClientTimeoutHTTP request timed out
GIONG-E1104HttpClientTooLargeHTTP response too large
GIONG-E1105HttpClientRedirectredirect not followed
GIONG-E1106HttpClientClosedconnection closed before the response
GIONG-E1107HttpClientProtocolmalformed HTTP response
GIONG-E1108HttpClientStatusHTTP error status
GIONG-E1109HttpClientDecodecannot decode the response body
GIONG-E1110HttpClientProxythe HTTP proxy refused the request
giong-web13 codes
GIONG-E1201WebInvalidRouteinvalid route pattern
GIONG-E1202WebDuplicateRouteroute added twice
GIONG-E1203WebNoRouteno route for the path
GIONG-E1204WebMethodNotAllowedmethod not allowed
GIONG-E1205WebBadParameterinvalid path or query parameter
GIONG-E1206WebNoSuchParameterthe route has no such parameter
GIONG-E1207WebBadBodyunreadable request body
GIONG-E1208WebUnsupportedMediaTypeunsupported Content-Type
GIONG-E1209WebTimeoutno response in time
GIONG-E1210WebInternalthe handler failed
GIONG-E1211WebUnavailablea service the handler needs is unavailable
GIONG-E1212WebCorsRejectedcross-origin request refused
GIONG-E1213WebConfiginvalid giong-web setting
giong-tls8 codes
GIONG-E2001NoTrustedRootsno trusted certificate authorities
GIONG-E2002BadCertificateDataunreadable certificate data
GIONG-E2003InvalidServerNameinvalid TLS server name
GIONG-E2004TlsCertificatecertificate rejected
GIONG-E2005TlsProtocolTLS protocol error
GIONG-E2006TlsHandshakeTimeoutTLS handshake timed out
GIONG-E2007TlsHandshakeEofconnection closed during the TLS handshake
GIONG-E2008TlsBrokenTLS stream broken
giong-postgres11 codes
GIONG-E3001PostgresConfiginvalid PostgreSQL configuration
GIONG-E3002PostgresConnectcannot connect to PostgreSQL
GIONG-E3003PostgresAuthPostgreSQL authentication failed
GIONG-E3004PostgresServerPostgreSQL server error
GIONG-E3005PostgresTypePostgreSQL type mismatch
GIONG-E3006PostgresRowCountwrong number of rows
GIONG-E3007PostgresTooLargePostgreSQL result too large
GIONG-E3008PostgresClosedPostgreSQL connection closed
GIONG-E3009PostgresPoolTimeoutPostgreSQL pool wait timed out
GIONG-E3010PostgresProtocolPostgreSQL protocol error
GIONG-E3011PostgresStatementstatement refused before sending
giong-mysql11 codes
GIONG-E3101MysqlConfiginvalid MySQL configuration
GIONG-E3102MysqlConnectcannot connect to MySQL
GIONG-E3103MysqlAuthMySQL authentication failed
GIONG-E3104MysqlServerMySQL server error
GIONG-E3105MysqlTypeMySQL type mismatch
GIONG-E3106MysqlRowCountwrong number of rows
GIONG-E3107MysqlTooLargeMySQL result too large
GIONG-E3108MysqlClosedMySQL connection closed
GIONG-E3109MysqlPoolTimeoutMySQL pool wait timed out
GIONG-E3110MysqlProtocolMySQL protocol error
GIONG-E3111MysqlStatementstatement refused before sending
giong-redis11 codes
GIONG-E3201RedisConfiginvalid Redis configuration
GIONG-E3202RedisConnectcannot connect to Redis
GIONG-E3203RedisAuthRedis authentication failed
GIONG-E3204RedisServerRedis server error
GIONG-E3205RedisTypeRedis type mismatch
GIONG-E3206RedisCommandcommand refused before sending
GIONG-E3207RedisTooLargeRedis reply too large
GIONG-E3208RedisClosedRedis connection closed
GIONG-E3209RedisPoolTimeoutRedis pool wait timed out
GIONG-E3210RedisProtocolRedis protocol error
GIONG-E3211RedisTimeoutRedis reply timed out

Generated from docs/errors/README.md

When giong is the wrong choice

Linux only

Kernel 6.0 or newer. An epoll driver for machines where io_uring is blocked is on the roadmap; there will be no kqueue or IOCP in production.

Not Tokio's ecosystem

Crates that need the Tokio runtime (hyper, sqlx, reqwest) do not run on giong. Crates that only use std::future do.

No HTTP/2

giong-http speaks HTTP/1.1. A request body over the limit is refused.

No kTLS

TLS runs in user space on rustls, and certificates are not reloaded for you.

Running tasks stay put

New work can go to the least busy worker (spawn_balanced, bind_balanced), but a task never moves once it has started.

Some gaps

Names come from /etc/hosts and DNS, not mDNS or LDAP. Also missing: Unix datagram sockets, multicast, file locks.

Pick something else when

Monoio is the mature choice and runs in production at ByteDance. If you need HTTP/2 or Tokio-compatible crates today, use it.

Glommio is built for storage engines: Direct I/O and priority scheduling are its strengths.

Tokio is the general-purpose runtime. giong is not trying to replace it for every workload.

Questions people ask

Is giong ready for production?

Not yet. It is complete enough to write real services and is tested hard, but it has not run in production. 1.0 waits for, among other things, at least one production user reporting back.

Does it run on macOS or Windows?

No. io_uring is a Linux interface. On Windows use WSL2 with a 6.x kernel (uname -r; wsl --update if it is older); on macOS a Linux virtual machine. In Docker, allow io_uring as docs/DEPLOYMENT.md shows.

Which Linux kernel do I need?

6.0 or newer, 6.1 or newer recommended. giong tries three ring setups in order: DEFER_TASKRUN (6.1+), COOP_TASKRUN (6.0), then no flags.

Can I use hyper, reqwest, sqlx or other Tokio crates?

Not crates that need the Tokio runtime; giong has its own HTTP, TLS, PostgreSQL, MySQL and Redis crates instead. Crates that only use std::future work. Adapters for the futures-io and Tokio I/O traits are on the roadmap.

Is it faster than Tokio?

Sometimes, and the benchmarks page says where. Small responses at 50 connections are a tie. giong makes about 0.03 system calls per request against 2.05, spends the least CPU per request at 5,000 connections, and reads files 5.5 times faster than Tokio on one core. Every number is over loopback on one machine.

How do I report a security problem?

Privately, through GitHub's private vulnerability reporting (the Security link at the bottom of every page), not in a public issue.

Why the name?

After Thánh Gióng, the child of Vietnamese legend who lay silent for three years and then rose a giant: next to nothing while idle, every core the moment load arrives.

Work on giong

Read CONTRIBUTING.md first; coding agents have AGENTS.md. Open an issue before anything larger than a fix.

git clone https://github.com/giong-run/Giong.git && cd Giong
cargo test --workspace --all-features   # the whole suite, every crate