Pingora 0.9.0
0.9.0 - 2026-09-04
- Reworked connection pooling with sharded storage and a true global LRU, addressing stale entries and race windows.
- Added an upstream module system that applies before upstream compression.
- More handling of HTTP parsing and framing edge cases, including non-origin-form request-target preservation, and hop-by-hop header sanitization, obsolete line-fold normalization, stricter request-target validation, and bounded default HTTP/2 limits.
- Split Prometheus integration into the pingora-prometheus crate and made Prometheus optional.
- Improved graceful shutdown and upgrade behavior, including responsive load-balancer shutdown, descriptor lifecycle fixes, and lower shutdown-notification contention.
- Minimum supported Rust version moves to 1.85 for some crates. pingora-foundations declares an MSRV of 1.88.
- RequestHeader and ResponseHeader no longer implement DerefMut because unrestricted mutation could violate internal invariants.
- Removed async_write_vec APIs; consumers should use tokio::io::AsyncWriteExt::write_all_buf.
- Prometheus integration moved from pingora-core to the separate pingora-prometheus crate; Prometheus is optional.
- tracing is now optional in pingora-cache.
- Upgraded to the boring-rs 5.x API.
- PeerOptions::curve now uses Cow.
- Upstream requests strip hop-by-hop and Connection-nominated headers by default; legacy behavior requires explicit compatibility settings.
- Default HTTP/2 server limits are bounded rather than unbounded.
- Removed the unused LruShard Default implementation and lifted Default bounds on sharded cache structures.
- Removed the CacheKey namespace parameter.
- PurgeOutcome enum gains an Expired variant.
- ForcedFreshness and hit-status reporting gain ForceExpiredServeStale variant.
- Add abort-on-close session configurability.
- Support HTTP/1.1 downstream request pipelining.
- Add cancel-safe body and header writer primitives (proxy tasks) to prevent stalled cache misses from applying backpressure.
- Add an upstream module system and allow modules to adjust after receiving upstream response headers.
- Add proxy warning-log suppression hooks.
- Add keepalive-pool callbacks for tracking connection ages.
- Expose HTTP/1.x request-body bytes accepted by the upstream writer.
- Report point-in-time available HTTP/2 stream capacity.
- Add ability to configure an offload thread pool for downstream TLS handshakes.
- Add Acceptor::from_server_config for runtime-built rustls ServerConfig values and in-memory key material.
- Export TLS keying material, including from pingora-s2n.
- Add per-peer CA configuration.
- Add a pre-TLS callback for PROXY protocol support.
- Expose the rustls certificate type.
- Add curve and second-keyshare settings to HttpPeer hashing.
- Avoid compiling aws-lc-rs when the ring provider is selected.
- Allow sharing backends across load-balancing selectors.
- Add graceful-upgrade signalling between old and new processes.
- Add per-listener L4 buffer configuration and socket send/receive buffer settings.
- Add Tokio blocking-pool configuration, poll-time histograms, and an alternative timer runtime knob.
- Allow proxy services to override runtime options.
- Add a working-directory option for daemon mode.
- Enable adding user context between sessions on the same connection with HttpPersistentSettings.
- Add socket-cookie access and TCP/TLS establishment timing fields.
- Make HTTP/2 stream and connection windows configurable.
- Add deferred cache-admission policy hooks.
- Implement DCZ dictionary compression and vary on available-dictionary.
- Add CacheMeta freshness updates and expiration-at-time support.
- Support optionally flooring fractional delta-seconds for RFC 9111 handling.
- Preserve Vary provenance across stale refreshes.
- Make cache-lock retries configurable and bounded.
- Add an opt-in purge mode that expires an asset while retaining its body for conditional revalidation and stale serving.
- Use power-of-two selection for eviction balancing.
- Add peek_lru, update_or_admit, and non-promoting set_weight operations in lru.
- Allow adjusting LRU weight limits and reserving capacity.
- HTTP ambiguity hardening: centralize raw request-target classification so path and authority validation share one parser; reject ambiguous request authorities on ingress and egress; reject forbidden CR/LF bytes in HTTP/2 :path; and reject delimiter bytes in request lines as defense in depth.
- Sanitize hop-by-hop upstream request headers.
- Preserve non-origin-form request targets without mangling the URI.
- Normalize forwarded responses with obsolete HTTP/1.1 response-header line folding.
- Bound default HTTP/2 server limits to reduce memory-exhaustion exposure.
- Avoid a process abort while appending oversized header maps by returning an InvalidHTTPHeader error.
- Fix some unchecked integer conversions.
- Explicitly prevent reuse of HTTP/1 connections after incomplete responses.
- Update Prometheus for a security advisory.
- Replaced unmaintained daemonize crate with daemonix and updated nix to 0.31.x.
- Fix connection-pool and PoolNode race windows and remove empty entries.
- Fixed a potential stall on HTTP/1 response-header reads upon forwarding request bodies via a cancel safety fix.
- Stop waiting on HTTP/2 upstream work after the downstream ends and close timed-out HTTP/2 connections.
- Drain in-flight HTTP/2 streams during shutdown and retry stream creation on a fresh connection when appropriate.
- Prevent HTTP/1 upstream reuse after failed writes or incomplete responses.
- Discard retry buffers after truncation and avoid unnecessary HTTP/2 accept allocations.
- Skip h2c preface detection on TLS streams.
- Do not initialize a body reader for HEAD informational responses.
- Correct HTTP/1 session body-byte accounting.
- Fix listener-fd inheritance and close transfer sockets during graceful upgrade; mark received listener fds close-on-exec.
- Remove the duplicate graceful-shutdown sleep and improve load-balancer shutdown responsiveness.
- Shard proxy shutdown notifications to reduce lock contention and close a lost-wakeup race during graceful shutdown.
- pingora-timeout now uses Tokio timeouts for (configurably) long intervals to avoid memory accumulation.
- Split pingora-prometheus into a separate crate.
- Forward WriteBuf::chunks_vectored to the wrapped buffer.
- Replace custom ASCII-trimming helpers with stabilized standard-library methods.
- Update the MSRV lane and use cargo check for MSRV validation.
- Improve documentation examples for connection tracing and basic setup.
- Preserve bound ports in digests after TLS failures.
- Return an error for divergent multipart cache progress and remove a panic from maybe_cache_meta.
- Various flaky test fixes.
Pingora 0.8.1
0.8.1 - 2026-06-04
🔒 Security
- Bound default HTTP/2 server limits to mitigate memory exhaustion.
- Upgrade Rustls-related dev-dependencies to address
rustls-webpkisecurity advisories.
⚙️ Miscellaneous Tasks
- Pin tracing dependencies to preserve Rust 1.84 compatibility.
- Use
cargo checkfor MSRV verification instead of compiling dev-dependencies during tests. - Update the Semgrep OSS scanning workflow.
- Use valid paths in header serialization tests.
- Gate HTTP/1 CONNECT tests on patched HTTP/1 support.
Pingora 0.8.0
0.8.0 - 2026-03-02
🚀 Features
- Add support for client certificate verification in mTLS configuration.
- Add upstream_write_pending_time to Session for upload diagnostics.
- Pipe subrequests utility: creates a state machine to treat subrequests as a "pipe," enabling direct sending of request body and writing of response tasks, with a handler for error propagation and support for reusing a preset or captured input body for chained subrequests.
- Add the ability to limit the number of times a downstream connection can be reused
- Add a system for specifying and using service-level dependencies
- Add a builder for pingora proxy service, e.g. to specify ServerOptions.
🐛 Bug Fixes
- Fix various Windows compiler issues.
- Handle custom ALPNs in s2n impl of ALPN::to_wire_protocols() to fix s2n compile issues.
- Fix: don't use “all” permissions for socket.
- Fix a bug with the ketama load balancing where configurations were not persisted after updates.
- Ensure http1 downstream session is not reused on more body bytes than expected.
- Send RST_STREAM CANCEL on application read timeouts for h2 client.
- Start close-delimited body mode after 101 is received for WebSocket upgrades.
UpgradedBodyis now an explicit HttpTask. - Avoid close delimit mode on http/1.0 req.
- Reject invalid content-length http/1 requests to eliminate ambiguous request framing.
- Validate invalid content-length on http/1 resp by default, and removes content-length from the response if transfer-encoding is present, per RFC.
- Correct the custom protocol code for shutdown: changed the numeric code passed on shutdown to 0 to indicate an explicit shutdown rather than a transport error.
⚙️ Miscellaneous Tasks
- Remove
CacheKey::defaultimpl, users of caching should implementcache_key_callbackthemselves - Allow server bootstrapping to take place in the context of services with dependents and dependencies
- Don't consider "bytes=" a valid range header: added an early check for an empty/whitespace-only range-set after the
bytes=prefix, returning 416 Range Not Satisfiable, consistent with RFC 9110 14.1.2. - Strip {content, transfer}-encoding from 416s to mirror the behavior for 304 Not Modified responses.
- Disable CONNECT method proxying by default, with an option to enable via server options; unsupported requests will now be automatically rejected.
Pingora 0.7.0
0.7.0 - 2026-01-30
- Extensible SslDigest to save user-defined TLS context
- Add ConnectionFilter trait for early TCP connection filtering
- Add ConnectionFilter trait for early TCP connection filtering
- Introduce a virtual L4 stream abstraction
- Add support for verify_cert and verify_hostname using rustls
- Exposes the HttpProxy struct to allow external crates to customize the proxy logic.
- Exposes a new_mtls method for creating a HttpProxy with a client_cert_key to enable mtls peers.
- Add SSLKEYLOGFILE support to rustls connector
- Allow spawning background subrequests from main session
- Allow Extensions in cache LockCore and user tracing
- Add body-bytes tracking across H1/H2 and proxy metrics
- Allow setting max_weight on MissFinishType::Appended
- Allow adding SslDigestExtensions on downstream and upstream
- Add Custom session support for encapsulated HTTP
- Use write timeout consistently for h2 body writes
- Prevent downstream error prior to header from canceling cache fill
- Fix debug log and new tests
- Fix size calculation for buffer capacity
- Fix cache admission on header only misses
- Fix duplicate zero-size chunk on cache hit
- Fix chunked trailer end parsing
- Lock age timeouts cause lock reacquisition
- Fix transfer fd compile error for non linux os
- Removed atty
- Upgrade lru to >= 0.16.3 crate version because of RUSTSEC-2026-0002
- Add tracing to log reason for not caching an asset on cache put
- Evict when asset count exceeds optional watermark
- Remove trailing comma from Display for HttpPeer
- Make ProxyHTTP::upstream_response_body_filter return an optional duration for rate limiting
- Restore daemonize STDOUT/STDERR when error log file is not specified
- Log task info when upstream header failed to send
- Check cache enablement to determine cache fill
- Update meta when revalidating before lock release
- Add ForceFresh status to cache hit filter
- Pass stale status to cache lock
- Bump max multipart ranges to 200
- Downgrade Expires header warn to debug log
- CI and effective msrv bump to 1.83
- Add default noop custom param to client Session
- Use static str in ErrorSource or ErrorType as_str
- Use bstr for formatting byte strings
- Tweak the implementation of and documentation of
connection_filterfeature - Set h1.1 when proxying cacheable responses
- Add or remove accept-ranges on range header filter
- Update msrv in github ci, fixup .bleep
- Override request keepalive on process shutdown
- Add shutdown flag to proxy session
- Add ResponseHeader in pingora_http crate's prelude
- Add a configurable upgrade for pingora-ketama that reduces runtime cpu and memory
- Add to cache api spans
- Increase visibility of multirange items
- Use seek_multipart on body readers
- Log read error when reading trailers end
- Re-add the warning about cache-api volatility
- Default to close on downstream response before body finish
- Ensure idle_timeout is polled even if idle_timeout is unset so notify events are registered for h2 idle pool, filter out closed connections when retrieving from h2 in use pool.
- Add simple read test for invalid extra char in header end
- Allow customizing lock status on Custom NoCacheReasons
- Close h1 conn by default if req header unfinished
- Add configurable retries for upgrade sock connect/accept
- Deflake test by increasing write size
- Make the version restrictions on rmp and rmp-serde more strict to prevent forcing consumers to use 2024 edition
- Rewind preread bytes when parsing next H1 response
- Add epoch and epoch_override to CacheMeta
Pingora 0.6.0
0.6.0 - 2025-08-15
- This release bumps the minimum h2 crate dependency to guard against the MadeYouReset H2 attack
- Log runtime names during Server shutdown
- Enabling tracking the execution phase of a server
- Allow using in-memory compression dicts
- Make H2Options configurable at HttpServer, HttpProxy Also adds HttpServerOptions to the HttpServer implementation, and updates the HttpEchoApp to use HttpServer for easier adhoc testing.
- Fix: read body without discard
- Try loading each LRU shard individually and warn on errors
- Update LRU save to disk to be atomic
- Allow cache to spawn_async_purge
- Pass hit handler in hit filter
- Cache hit filter can mutate cache, allow resetting cache lock
- Persist keepalive_timeout between requests on same stream
- Properly check for H2 io ReadError retry types
- Add cache lock wait timeout for readers
- Fix CacheLock status timeout conditions
- Handle close on partial chunk head
- Allow optional to reset session timeouts
- Clippy fixes for 1.87, add 1.87 to GitHub CI
- Run
range_{header,body}_filterafter disabling cache - Convert
InterpretCacheControlmembers toDuration - Disable downstream ranging on max file size
- Allow explicit infinite keepalive timeout to be respected Note that a necessary follow up is to refactor the infinite keepalive timeout to only apply to first read between requests on reused conns.
- Add method to disable keepalive if downstream is unfinished
- Discard extra upstream body and disable keepalive
- Explicitly disable keepalive on upstream connection when excess body (content-length) is detected.
- Add brief sleep to shutdown signal tests to avoid flake
- Allow override of cache lock timeouts
- Allow arbitrary bytes in CacheKey instead of just Strings
- Corrects out-of-order data return after multiple peek calls with different buffer sizes.
- Mark previously too large chunked assets as cacheable
- Boring/OpenSSL load cert chain from connector options
- Add initial support for multipart range requests
- Adds a callback to HttpHealthCheck for collecting detailed backend summary information
- Multipart range filter state fixes
- Explanation of request_body_filter phase
Pingora 0.5.0
0.5.0 - 2025-05-09
- Add tweak_new_upstream_tcp_connection hook to invoke logic on new upstream TCP sockets prior to connection
- Add ability to configure max retries for upstream proxy failures
- Allow tcp user timeout to be configurable
- Add peer address to downstream handshake error logs
- Allow proxy to set stream level downstream read timeout
- Improve support for sending custom response headers and bodies for error messages
- Allow configuring multiple listener tasks per endpoint
- Add get_stale and get_stale_while_update for memory-cache
- Fix deadloop if proxy_handle_upstream exits earlier than proxy_handle_downstream
- Check on h2 stream end if error occurred for forwarding HTTP tasks
- Check for content-length underflow on end of stream h2 header
- Correctly send empty h2 data frames prior to capacity polling
- Signal that the response is done when body write finishes to avoid h1 downstream/h2 upstream errors
- Ignore h2 pipe error when finishing an H2 upstream
- Add finish_request_body() for HTTP healthchecks so that H2 healthchecks succeed
- Fix Windows compile errors by updating
impl<T> UniqueIDto use correct return type - Fixed compilation errors on Windows
- Poll for H2 capacity before sending H2 body to propagate backpressure
- Fix for write_error_response for http2 downstreams to set EOS
- Always drain v1 request body before session reuse
- Fixes HTTP1 client reads to properly timeout on initial read
- Fixes issue where if TLS client never sends any bytes, hangs forever
- Add builder api for pingora listeners
- Better handling for h1 requests that contain both transfer-encoding and content-length
- Allow setting raw path in request to support non-UTF8 use cases
- Allow reusing session on errors prior to proxy upstream
- Avoid allocating large buffer in the accept() loop
- Ensure HTTP/1.1 when forcing chunked encoding
- Reject if the HTTP header contains duplicated Content-Length values
- proxy_upstream_filter tries to reuse downstream by default
- Allow building server that avoids std::process::exit during shutdown
- Update Sentry crate to 0.36
- Update the bounds on
MemoryCachemethods to accept broader key types - Flush already received data if upstream write errors
- Allow modules to receive HttpTask::Done, flush response compression on receiving Done task
- API signature changes as part of experimental proxy cache support
- Note MSRV was effectively bumped to 1.82 from 1.72 due to a dependency update, though older compilers may still be able to build by pinning dependencies, e.g.
cargo update -p backtrace --precise 0.3.74.
Pingora 0.4.0
0.4.0 - 2024-11-01
- Add preliminary rustls support
- Add experimental support for windows
- Add the option to use no TLS implementation
- Add support for gRPC-web module to bridge gRPC-web client requests to gRPC server requests
- Add the support for h2c and http1 to coexist
- Add the support for custom L4 connector
- Support opaque extension field in Backend
- Add the ability to ignore informational responses when proxying downstream
- Add un-gzip support and allow decompress by algorithm
- Add the ability to observe backend health status
- Add the support for passing sentry release
- Add the support for binding to local port ranges
- Support retrieving rx timestamp for TcpStream
- Handle bare IPv6 address in raw connect Host
- Set proper response headers when compression is enabled
- Check the current advertised h2 max streams
- Other bug fixes and improvements
- Make sentry an optional feature
- Make timeouts Sync
- Retry all h2 connection when encountering graceful shutdown
- Make l4 module pub to expose Connect
- Auto snake case set-cookie header when downgrade to from h2 to http1.1
- shutdown h2 connection gracefully with GOAWAYs
- Other API signature updates
Full Changelog: https://github.com/cloudflare/pingora/compare/0.3.0...0.4.0
Pingora 0.3.0
0.3.0 - 2024-07-12
- Add support for HTTP modules. This feature allows users to import modules written by 3rd parties.
- Add
request_body_filter. Now request body can be inspected and modified. - Add H2c support.
- Add TCP fast open support.
- Add support for server side TCP keep-alive.
- Add support to get TCP_INFO.
- Add support to set DSCP.
- Add
or_err()/or_err_withAPI to convertOptionstopingora::Error. - Add
or_fail()API to convertimpl std::error::Errortopingora::Error. - Add the API to track socket read and write pending time.
- Compression: allow setting level per algorithm.
- Fixed a panic when using multiple H2 streams in the same H2 connection to upstreams.
- Pingora now respects the
Connectionheader it sends to upstream. - Accept-Ranges header is now removed when response is compressed.
- Fix ipv6_only socket flag.
- A new H2 connection is opened now if the existing connection returns GOAWAY with graceful shutdown error.
- Fix a FD mismatch error when 0.0.0.0 is used as the upstream IP
- Dependency: replace
structoptwithclap - Rework the API of HTTP modules
- Optimize remove_header() API call
- UDS parsing now requires the path to have
unix:prefix. The support for the path without prefix is deprecated and will be removed on the next release. - Other minor API changes
Pingora 0.1.1
0.1.1 - 2024-04-05
Server::newnow acceptsInto<Option<T>>- Implemented client
HttpSession::get_keepalive_valuesfor Keep-Alive parsing - Expose
ListenFdsandFdsto fix a voldemort types issue - Expose config options in
ServerConf, provide newServerconstructor upstream_response_filternow runs on upstream 304 responses during cache revalidation- Added
server_addrandclient_addrAPIs toSession - Allow body modification in
response_body_filter - Allow configuring grace period and graceful shutdown timeout
- Added TinyUFO sharded skip list storage option
- Fixed build failures with the
boringsslfeature - Fixed compile warnings with nightly Rust
- Fixed an issue where Upgrade request bodies might not be handled correctly
- Fix compilation to only include openssl or boringssl rather than both
- Fix OS read errors so they are reported as
ReadErrorrather thanReadTimeoutwhen reading http/1.1 response headers
- Performance improvements in
pingora-ketama - Added more TinyUFO benchmarks
- Added tests for
pingora-cachepurge - Limit buffer size for
InvalidHTTPHeadererror logs - Example code: improvements in pingora client, new LB cluster example
- Typo fixes and clarifications across comments and docs