For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
Sign inTry it free
DocsGuidesSDKsIntegrationsAPI docsTutorialsFlagship blog
DocsGuidesSDKsIntegrationsAPI docsTutorialsFlagship blog
  • Tutorials
    • The AI Iteration Loop for Deploying Reliable Agents with LangGraph
    • Using LaunchDarkly feature flags and Experimentation with Wordpress
    • Migrate a Hardcoded LangGraph Agent to LaunchDarkly AgentControl in 20 Minutes
    • Offline Evaluation of RAG-Grounded Answers in AgentControl
    • Beyond n8n for Workflow Automation: Agent Graphs as Your Universal Agent Harness
    • Catch your first silent AI failure with Vega AI in under 10 minutes
    • Evaluate LLM code generation with LLM-as-judge evaluators
    • OpenTelemetry for LLM Applications: A Practical Guide with LaunchDarkly and Langfuse
    • Use LaunchDarkly Agent Skills in Claude Code and Cursor
    • Detection to Resolution: Real World Debugging with Rage Clicks and Session Replay
    • Compare AI orchestrators: LangGraph vs Strands vs OpenAI Swarm
    • Building a data extraction pipeline with LaunchDarkly
    • Day 12 | 🎊 New Year, New Observability
    • Day 11 | ✉️ Letters to Santa: What engineering teams really want from Observability in 2026
    • Day 10 | Why observability and feature flags go together like milk and cookies
    • Day 9 | 👻 The Three Ghosts Haunting Your AI This Holiday Season
    • Day 7 | 🎄✨The Rockefeller tree in NYC: SLOs that actually drive decisions
    • Day 6 | 💸 The famous green character that stole your cloud budget: the cardinality problem
    • Day 5 | 🧹 Using a Popular Tidying Method to Consolidate Your Observability Stack
    • Day 4 | ❄️ Tracing the impact of holiday styling in your Node.js app
    • Day 8 | 🎁 Observable Multi-Modal Agentic Systems
    • Day 3 | 🔔 Jingle All the Way to Zero-Config Observability
    • Day 2 | 🎅 He knows if you have been bad or good... But what if he gets it wrong?
    • Collecting user feedback in your app with feature flags
    • Day 1 | 🎄 Observability Under the Tree: What Changed in 2025
    • Build a User Frustration Detection & Response System
    • When to Add Online Evals to Your AgentControl
    • Detecting User Frustration: Understanding Rage Clicks and Session Replay
    • AgentControl config CI/CD Pipeline: Automated Quality Gates and Safe Deployment
    • A Deeper Look at LaunchDarkly Architecture: More than Feature Flags
    • Add Observability to Your React Native App in 5 minutes
    • Smart AI Agent Targeting with MCP Tools
    • Build a LangGraph Multi-Agent System in 20 Minutes with LaunchDarkly AgentControl
    • Snowflake Cortex Completion API + LaunchDarkly SDK Integration
    • Using AgentControl to review database changes
    • How to implement WebSockets and kill switches in a Python application
    • 4 hacks to turbocharge your Cursor productivity
    • Create a feature flag in your IDE in 5 minutes with LaunchDarkly's MCP server
    • Observability for Your Go ORM: OpenTelemetry Integration with GORM
    • The complete guide to OpenTelemetry in Next.js
    • How to instrument your React Native app with OpenTelemetry
    • The complete guide to OpenTelemetry in Python
    • Monitoring Browser Applications with OpenTelemetry
    • How to Use OpenTelemetry to Monitor Next.js Applications
    • What is OpenTelemetry and Why Should I Care?
    • Distributed Tracing in Next.js Apps
    • Tracing Distributed Systems in Next.js
    • Real-time Monitoring in Django: Essential Tools and Techniques
    • DeepSeek vs Qwen: local model showdown featuring LaunchDarkly AgentControl
    • Application Tracing in .NET for Performance Monitoring
    • The Ultimate Guide to Ruby Logging: Best Libraries and Practices
    • Using Materialized Views in ClickHouse (vs. Postgres)
    • Filtering and Sampling LaunchDarkly Ingest
    • How to Set Up Your Production AWS MSK Kafka Cluster
    • Publishing an NPM Package with Private pnpm Monorepo Dependencies
    • How To Use The Chrome Inspector & Debugger
    • 3 Levels of Data Validation in a Full Stack Application With React
    • The power of the monorepo: Keep your fullstack app in sync!
    • Compression: The simple, powerful upgrade for your web stack
    • Video tutorials
Sign inTry it free
LogoLogo
On this page
  • What is compression and how can it help me?
  • What are common compression algorithms out there?
  • Brotli at LaunchDarkly
  • The Code Changes
  • Installing Dependencies
  • Enabling Brotli Compression
Tutorials

Compression: The simple, powerful upgrade for your web stack

Was this page helpful?
Previous

Video tutorials

Next
Built with

Published August 1, 2022

portrait of John Pham.

by John Pham

At LaunchDarkly, we’re super focused on keeping our app snappy and fast. Given our product, we take responsibility for making sure that our users are able to quickly find the session/error/trace that identifies an issue as fast as possible.

Recently, we’ve been experimenting with quite a few methods to speed up larger request payloads on our GraphQL endpoints, and we found that compression has done wonders. Below, I’ll share an overview of compression in the modern web stack as well as some code that can get you started!

What is compression and how can it help me?

Simply put, compression algorithms recognize patterns in data and use these patterns to reduce the payload size sent across the wire. For the purpose of this discussion, we’ll focus on text compression, but for the most part, these concepts roll over to other types as well (sound, video, etc..).

In a modern web stack, because text is being sent over HTTP quite frequently (between your frontend and backend servers, for example), we can make use of patterns in this text to dramatically decrease the size of data. If this can be successfully done, your web server won’t have to send as much data which saves bandwidth. Beyond that, if the amount of time taken to compress the data is minimal, this can also give your app a performance/speed boost. Overall, because there are loads of libraries and frameworks out there that will do this for us, experimenting with compression in your web app is well worth the effort!

What are common compression algorithms out there?

From 1992 to 2013 or so, the most common compression algorithm used on the web was Gzip. Because it was quite fast and decreased size by a lot, it quickly became very ubiquitous, gaining support in all major web browsers and CDNs. Around 2013, Google published a new algorithm called Brotli, which performed even better than Gzip, and has been gaining popularity since. At this point, Brotli is supported by all major browsers and has a clear benefit over Gzip both from a speed and efficiency perspective, and this is what we use at LaunchDarkly!

Brotli at LaunchDarkly

As mentioned earlier, Brotli is supported on most modern browsers. For browsers that don’t support Brotli, however, the compression method will fall back to gzip based on the request’s `Accept-Encoding` header. This means that there’s little to no downside to enabling Brotli; it’s an easy performance win.

When we enabled Brotli compression for LaunchDarkly, we saw response sizes decrease around 40% with no latency increases (requests were faster!). We’re now using this on all of our API endpoints and there’s a clear difference in load times and bandwidth usage.

The Code Changes

Because of its ubiquity, most languages/frameworks will likely have a Brotli library that can be wrapped around the web server. At LaunchDarkly, we write a lot of Go, so below is an example for implementing Brotli compression in a Chi router.

Installing Dependencies

# Install the Chi, older versions of Chi don't support Brotli
go get -u github.com/go-chi/chi
# Install the package that will do the Brotli compression
go get -u gopkg.in/kothar/brotli-go.v0

Enabling Brotli Compression

r := chi.NewMux()
compressor := middleware.NewCompressor(5, "/*")
compressor.SetEncoder("br",func(w io.Writer, level int) io.Writer {
params := brotli_enc.NewBrotliParams()
params.SetQuality(level)return brotli_enc.NewBrotliWriter(params, w)})
r.Use(compressor.Handler)

The `”/*”` means to compress all content types that can be compressed. These are the supported types:

var defaultCompressibleContentTypes = {
"text/html",
"text/css",
"text/plain",
"text/javascript",
"application/javascript",
"application/x-javascript",
"application/json",
"application/atom+xml",
"application/rss+xml",
"image/svg+xml",
}

That’s it, congrats on the easy performance win for you and your users!