Getting Started with Envoy Proxy - Beginners Guide
Envoy is a high-performant edge and service proxy server like NGINX or HAProxy built in C++, designed for cloud-native applications.

Envoy is a high-performant edge and service proxy server like NGINX or HAProxy built in C++, designed for cloud-native applications. Envoy was initially developed at Lyft, it was later open-sourced for the community.
Envoy Features
- Smaller memory footprint compared to other proxy servers
- Supports HTTP/2 and gRPC for incoming and outgoing connections
- Supports advanced load balancing features including automatic retries, circuit breaking, global rate limiting, request shadowing, and zone local load balancing.
- Deep observability of L7 traffic, native support for distributed tracing, and wire-level observability of MongoDB, DynamoDB, and more.
Due to envoy's high performant and smaller memory footprint functionality, major companies have been moving away from Nginx to Envoy. One such company is dropbox. In 2020 dropbox migrated its services from NGINX to Envoy.
Companies that use envoy include Airbnb, Amazon, Booking.com, CookPad, Digitalocean, Dropbox, eBay, f5, Google, Grubhub, IBM, Medium, Microsoft, Netflix, Pinterest, Salesforce, Snapchat, Stripe, Square, Tencent, Twilio, Uber, Verizon, Vmware, Yahoo Japan, Yelp, VSCO.
Installing Envoy
Depending on your operating system there are several ways to install envoy. For this guide, I'll demonstrate how to install envoy on Debian.
sudo apt update
sudo apt install debian-keyring debian-archive-keyring apt-transport-https curl lsb-release
curl -sL 'https://deb.dl.getenvoy.io/public/gpg.8115BA8E629CC074.key' | sudo gpg --dearmor -o /usr/share/keyrings/getenvoy-keyring.gpg
echo a077cb587a1b622e03aa4bf2f3689de14658a9497a9af2c427bba5f4cc3c4723 /usr/share/keyrings/getenvoy-keyring.gpg | sha256sum --check
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/getenvoy-keyring.gpg] https://deb.dl.getenvoy.io/public/deb/debian $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/getenvoy.list
sudo apt update
sudo apt install getenvoy-envoy
Now that you have envoy installed let us get a deeper understanding of envoy architecture.
Envoy Architecture/Configuration
Envoy use yaml
format for envoy proxy configuration. Before starting writing the envoy .yaml
file you will either start with a node
, dynamic_resource
or static_resource
.
node
: it usually uniquely identifies the proxy node.
dynamic_resources
: These are configurations that should be updated dynamically.
static_resources
: specifies where Envoy should retrieve its configuration from.

What are listeners
, filter_chains
, and clusters
in envoy?
- listeners: This is where you configure the port and IP the envoy should be exposed on.
- filter_chains: Based on our needs
filter_chains
can differ. Basically,filter_chains
allows us to modify what happens to incoming and outgoing requests. Just like filters in photos. At least you should have a filter that defines how incoming/outgoing traffic should be routed from/to the internal backend/microservices. You can have morefilter_chains
apart from the one that routes traffic. - clusters: This is where the configuration for the backend/microservices resides. We can also define the type of load balancing we want to achieve in the cluster.
- admin: This usually displays sensitive monitoring information for the admin and should not be exposed to the public.
Now that we have an understanding of the different components used to write the envoy .yaml
below is a simple implementation.
Let's assume we have two microservices we want to proxy with envoy:
- Microservice A: A NextJS for our frontend running on port
3000
- Microservice B: A go API backend running on port
5000
We can achieve this in envoy like below:
static_resources:
listeners:
address:
socket_address:
address: 0.0.0.0
port_value: 8080
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
access_log:
- name: envoy.access_loggers.stdout
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match:
prefix: "/api/"
route:
prefix_rewrite: "/"
cluster: my_backend
- match:
prefix: "/"
route:
cluster: my_frontend
clusters:
- name: my_frontend
type: STRICT_DNS
connect_timeout: 0.25s
load_assignment:
cluster_name: next_app
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 3000
- name: my_backend
type: STRICT_DNS
connect_timeout: 0.25s
load_assignment:
cluster_name: go_backend
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 5000
admin:
access_log_path: "/dev/null"
address:
socket_address:
address: 0.0.0.0
port_value: 8001
prefix_rewrite: "/"
on the route filter to remove envoy path prefix from reaching our backend. Instead, we rewrite /api
to /
.To run envoy run:
envoy -c envoy-config.yaml
Conclusion
Envoy is a highly performant edge proxy despite its steep learning curve. This is why every big cooperation uses Envoy in one way or another. The best way to use envoy is with a service mesh control plane like Istio.