Skip to content

Repository files navigation

Socketify logo

Socketify

A fast, modern C++20 HTTP/HTTPS server & routing framework
Express-style ergonomics on an epoll event loop with zero-copy file serving.

C++20 CMake Linux epoll TLS Tests License Version

http · https · rest-api · middleware · sse · pulse · websocket · sessions · cors · rate-limit · gzip · static-files · sendfile · json · multipart · cookies · high-performance · zero-copy · web-framework · backend · cpp20 · cmake


Quick taste

#include <socketify/socketify.h>
using namespace socketify;

int main() {
    Server server;

    server.Get("/", [](Request&, Response& res) {
        res.send("Hello, world!\n");
    });

    server.Get("/users/:id", [](Request& req, Response& res) {
        res.json({{"id", req.params().at("id")}});
    });

    server.Listen(8080);
    server.Wait();
}

Features

  • HTTP/1.1 — keep-alive, pipelining, chunked transfer decoding, Expect: 100-continue, configurable header/body limits and timeouts
  • HTTPS — TLS 1.2+ via OpenSSL, cert/key from files or environment, one code path for HTTP and HTTPS
  • Routing:params, *wildcards, route groups, per-route and global middleware, automatic HEAD fallback and 405 handling
  • Request/response — lazy query/cookie parsing, JSON body (nlohmann::json), urlencoded forms, multipart file uploads, streaming/chunked responses, redirects
  • Static files — zero-copy sendfile(2), ETag/Last-Modified, Range requests, directory indexes, SPA fallthrough
  • Middleware built-ins — request logging (IP + status-aware levels), request IDs, CORS, token-bucket rate limiting (RateLimit-* headers), gzip/deflate compression, body-size limits
  • Sessions — pluggable manager: server store, signed cookie, or JWT (cookie / Bearer); rolling TTL, regenerate(), default MemoryStore
  • ORM / databasesocketify::db models & schema DSL for SQLite, PostgreSQL, MySQL; MongoDB documents (memory:// or mongo-cxx); migrations, validations, hooks, relations, pools, transactions
  • Server-Sent Eventssse::upgrade() with a thread-safe session handle for pushing events from any thread
  • Pulse — bidirectional realtime channels (pulse::upgrade / Channel / Hub); pulse_easy JSON events; pulse_media voice/video/image streaming; RFC 6455 WebSocket under the hood so browsers and wscat work unchanged
  • JSON helperssocketify::json_util dotted-path access, safe parse, req.json() / res.json_error()
  • Validationsocketify::validate declarative schemas for request bodies
  • Configsocketify::config typed env + .env file loader
  • Cachesocketify::cache thread-safe TTL key/value store with JSON helpers
  • HTTP clientsocketify::http_client synchronous GET/POST with optional TLS
  • Performance architecture — one epoll loop per worker thread, SO_REUSEPORT listeners (no accept contention), non-blocking sockets, buffered writes, timer-based connection expiry

Benchmarks

Charts are animated SVGs (transparent background; labels adapt to light/dark themes). Click a section to expand or collapse.

HTTP /ping — Socketify vs Express / Flask / Django

Same machine, same endpoint, same load tool.

What GET /ping{"ok":true} (no DB, no templates)
How wrk -t4 -c100 -d8s, localhost keep-alive
Where Intel i7-12700K · 20 threads · Linux · 2026-07-20

Throughput — requests / second

Throughput chart: Socketify vs Express, Flask, Django

Rank Framework req/s vs Socketify
1 Socketify (C++20 · epoll) 909,254
2 Express 4 (Node.js) 61,208 ~15× slower
3 Flask 3 + Waitress 1,862 ~488× slower
4 Django 4 + Waitress 1,202 ~757× slower

Latency — p99 (lower is better)

P99 latency chart: Socketify vs Express, Flask, Django

Framework avg p50 p99
Socketify 0.080 ms 0.054 ms 0.124 ms
Express 1.98 ms 1.57 ms 2.30 ms
Django 82.5 ms 90.5 ms 123 ms
Flask 86.3 ms 51.6 ms 1140 ms
Methodology & how to reproduce

Why Socketify wins this test: native C++20, epoll + SO_REUSEPORT workers, almost no per-request overhead. Interpreted stacks (Node / Python) pay runtime and middleware costs even on a trivial handler.

Public suites (different hardware — order only):

Source Express Flask Django
Sharkbench (2025-08) ~5,766 ~1,092 ~950
Commodity /ping write-up ~6,500 much lower w/ default middleware

Micro-benchmarks ≠ production apps (DB, auth, business logic dominate there). Always measure your workload. Raw JSON: benchmarks/results.json.

./benchmarks/run_all.sh
# optional: DURATION=10 CONCURRENCY=200 ./benchmarks/run_all.sh
Pulse (WebSocket) — why Pulse, echo & Hub fan-out

Pulse is RFC 6455 WebSocket on the wire (ws:// / wss://). Browsers, wscat, and Node clients work unchanged. You pick Pulse when you want that protocol plus Socketify Hub rooms, pulse_easy JSON events, pulse_media voice/video/image streaming, and the same C++ epoll server as your HTTP API — one process, one binary.

Raw WebSocket DIY Pulse
Browser / wscat compatible
Rooms + broadcast you write it pulse::Hub built-in
JSON event API you write it pulse_easy
Voice / video / image frames you write it pulse_media
Encode-once fan-out usually re-encode per peer broadcast_frame (~5.7× faster)
Same stack as HTTP/HTTPS often separate one Server

WebSocket echo — msg/s (same machine)

128 concurrent clients · 64-byte text echo · asyncio load client · 8s

Pulse vs Node ws vs Python WebSocket echo throughput

Rank Stack msg/s vs Pulse
1 ws (Node.js) 80,122 ~1.05× Pulse
2 Pulse (Socketify) 76,600
3 websockets (Python) 63,511 ~1.2× slower

Pulse vs Node ws vs Python WebSocket echo P99 latency

Stack avg p50 p99
Node ws 1.59 ms 1.58 ms 1.75 ms
Pulse 1.67 ms 1.66 ms 1.85 ms
Python websockets 2.01 ms 1.99 ms 2.58 ms

Echo is client-bound here (asyncio load gen) — Pulse sits in the same ballpark as Node ws and ahead of Python. The bigger win is Hub fan-out and the batteries above.

Pulse Hub fan-out — encode once (in-process)

1,000 peers · 256 B · broadcast_frame vs N× send_text re-encode

Pulse Hub encode-once vs per-peer re-encode

Approach delivered msg/s vs encode-once
Hub broadcast_frame (encode-once) 38,554,933
Naive per-peer send_text 6,802,453 ~5.7× slower
How to reproduce
./benchmarks/run_pulse.sh
# optional: DURATION=8 CLIENTS=128 ./benchmarks/run_pulse.sh
# Hub microbench: ./benchmarks/servers/pulse_hub_fanout 1000 2000

Raw numbers: pulse_results.csv · pulse_hub_results.csv

Requirements

Dependency Notes
Linux epoll / sendfile / SO_REUSEPORT
C++20 compiler GCC 12+ or Clang 15+
CMake ≥ 3.16
nlohmann_json ≥ 3.11
ZLIB gzip / deflate
OpenSSL 1.1.1+ optional; only when SOCKETIFY_WITH_TLS=ON (default)
# Debian / Ubuntu
sudo apt install build-essential cmake ninja-build \
    nlohmann-json3-dev zlib1g-dev libssl-dev

How to build

1. Clone (with examples submodules)

Ripple and other showcase apps live as git submodules under examples/. Clone with recursion so they come along:

git clone --recurse-submodules https://github.com/MSaLeHNYM/Socketify.git
cd Socketify

Already cloned without submodules?

git submodule update --init --recursive

2. Configure & build (Release)

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release \
    -DSOCKETIFY_BUILD_EXAMPLES=ON
cmake --build build -j$(nproc)

Or use the helper script:

./scripts/build_release.sh

3. Debug build + sanitizers + tests

./scripts/build_debug.sh
# equivalent to:
#   cmake -S . -B build-debug -DCMAKE_BUILD_TYPE=Debug \
#       -DSOCKETIFY_BUILD_TESTS=ON \
#       -DSOCKETIFY_SANITIZE=address,undefined
#   cmake --build build-debug -j$(nproc)
#   ctest --test-dir build-debug --output-on-failure

4. Install (optional)

cmake --install build --prefix /usr/local
# then in your app:
#   find_package(Socketify 0.2 REQUIRED)
#   target_link_libraries(app PRIVATE Socketify::socketify)

socketify --version
socketify --run-http ./public --port 8080

Version is read from the root VERSION file (see docs/VERSIONING.md). Bump with ./scripts/bump-version.sh patch|minor|major.

CMake options

Option Default Meaning
SOCKETIFY_WITH_TLS ON HTTPS support (needs OpenSSL)
SOCKETIFY_WITH_SQLITE ON SQLite driver for socketify::db
SOCKETIFY_WITH_POSTGRES OFF PostgreSQL driver (libpq)
SOCKETIFY_WITH_MYSQL OFF MySQL driver (libmysqlclient)
SOCKETIFY_WITH_MONGO OFF MongoDB driver (mongo-cxx); memory:// always available
SOCKETIFY_BUILD_CLI ON (top-level) Build/install the socketify manager binary
SOCKETIFY_BUILD_EXAMPLES OFF Build examples/
SOCKETIFY_BUILD_TESTS OFF Build GoogleTest suite
SOCKETIFY_BUILD_DOCS OFF Add a docs Doxygen target
SOCKETIFY_SANITIZE (empty) e.g. address,undefined
SOCKETIFY_WERROR OFF Treat warnings as errors

Convenience scripts:

Script What it does
scripts/build_release.sh Optimized Release build (+ examples)
scripts/build_debug.sh Debug + ASan/UBSan + tests
scripts/run_tests.sh Build (if needed) and run CTest
scripts/run_examples.sh [01-07] Build & run one graded example
scripts/serve_docs.sh [port] Generate Doxygen docs, serve on localhost, open browser
scripts/bump-version.sh Bump SemVer in VERSION (patch/minor/major)

Using it in your project

After cmake --install build:

find_package(Socketify 0.2 REQUIRED)
# Socketify_VERSION is set (e.g. "0.2.2")
target_link_libraries(app PRIVATE Socketify::socketify)
#include <socketify/version.h>
// SOCKETIFY_VERSION_STRING / socketify::version_string()

Or add Socketify as a subdirectory / FetchContent and link Socketify::socketify.

Examples — a graded tour

Example Shows
01_hello_world routes, path params, JSON
02_rest_api CRUD API, groups, body parsing, status codes
03_middleware logging, CORS, rate limit, sessions, custom auth
04_static_site static files, compression, SPA fallback
05_sse_chat live feed over Server-Sent Events
06_https TLS with a self-signed dev cert
07_fullstack everything combined: frontend + API + sessions + SSE
08_nexus_board React + SQLite app: auth, projects, kanban, uploads, live SSE
09_orm_demo socketify::db ORM: models, relations, migrations, Mongo documents
10_pulse_chat lobby chat over Pulse (browser WebSocket + pulse::Hub)
11_pulse_media Pulse Easy + voice/image relay via pulse_media
ripple Ripple — Telegram-style messenger (Pulse + SQLite + React) · submodule

Ripple

RippleMessages that ripple.
Full messenger showcase: accounts, DMs, groups, presence, typing indicators.
Built with Socketify Pulse + db ORM (SQLite) + React · MIT licensed.

./scripts/run_examples.sh 07       # fullstack guestbook
./scripts/run_examples.sh 10       # Pulse lobby chat
./scripts/run_examples.sh ripple   # Ripple messenger → http://localhost:8080

Tests

203 unit and integration tests (GoogleTest), run under AddressSanitizer/UBSan in the debug build:

./scripts/run_tests.sh

Documentation

  • Hand-written guide: docs/API.md
  • API reference (local only) — generate with the script; HTML is written to docs/generated/ which is gitignored (not pushed to GitHub):
./scripts/serve_docs.sh          # regen + http://127.0.0.1:8765/
./scripts/serve_docs.sh 9000     # custom port
./scripts/serve_docs.sh --regen-only

Requires doxygen on PATH (or under .deps/sysroot/usr/bin/doxygen).

Roadmap

  • Pulse permessage-deflate (optional compression extension)
  • HTTP/2 (ALPN, h2c)
  • Pluggable auth helpers (JWT, HMAC)
  • Redis-backed session/rate-limit stores
  • OpenTelemetry exporter

License & copyright

Copyright © 2025–2026 M SaLeH NYM. All rights reserved.

Socketify is released under a source-available license (see LICENSE):

You may You may not (without written permission)
Use Socketify as a library to build & ship your own apps Modify / fork / redistribute changed copies of Socketify
Link statically or dynamically against an unmodified build Treat Socketify as open-source-to-relicense

Want to contribute a patch? Ask first — email saleh.ue4@gmail.com or Telegram t.me/MSaLeHNYM for permission. Approved contributions are assigned to the copyright holder so ownership stays unified.

All copyright and legal ownership of this software belong exclusively to M SaLeH NYM.

About

Fast C++20 HTTP/HTTPS web framework for Linux — epoll + SO_REUSEPORT, zero-copy sendfile, routing, middleware, TLS, SSE, sessions & JSON. Express-style API built for performance.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages