Skip to content
Let’s plan the right software for your processes. Call us for a demo or a quote: +90 546 737 48 29

TR EN DE

What is a reverse proxy?

A reverse proxy is a server that receives requests from visitors on behalf of your servers and passes them to the application behind it. When a visitor connects to your domain, they are in fact talking to the reverse proxy; they do not know whether there is one server or ten at the back, which language the application is written in or which port it runs on.

A comparison: the reception desk of an organisation. Everyone who arrives goes to the desk first; the desk checks who they are, directs them to the right department and answers simple questions itself. The departments have no door onto the street. A reverse proxy does the same job for web traffic. Nginx is one of the most widely used pieces of software for this; it is introduced in the Nginx guide, and the proxy concept in general is covered in the proxy server guide.

In brief

  • A reverse proxy is the single entry point that sits between visitors and your application servers.
  • Certificates, load balancing, caching, compression and rate limiting are managed in one place.
  • The backend learns the visitor's real address and the protocol only from the forwarded headers.
  • A reverse proxy is a single point of failure; timeouts and redundancy should be considered from the start.
On this page

What does a reverse proxy do?

  1. Where it sits: the difference from a forward proxy

    Both kinds sit in the middle, but they serve different sides:

    • A forward proxy is in front of the client and goes out to the internet on its behalf. It is used on company networks to control outgoing traffic.
    • A reverse proxy is in front of the server and receives requests on its behalf. The site owner sets it up; the visitor does not need to configure anything and is not even aware that it exists.

    The servers behind the reverse proxy are called backend servers (upstream in Nginx configuration). A backend can be a PHP, Node.js, Java or Python application, another web server or a container.

    Diagram: a forward proxy sits in front of the client, a reverse proxy in front of the server; the visitor only talks to the reverse proxy : Enlarge
  2. The jobs it takes on

    • Single entry point: All requests come in through one address and one port. Only the reverse proxy is opened to the internet in the firewall; access logs are collected in one place.
    • SSL/TLS termination: The certificate is installed on the reverse proxy and the encrypted connection is decrypted there. There is no need to install and renew a separate certificate for each application.
    • Load balancing: Requests are spread across several backend servers; if one does not respond, the request is sent to the others.
    • Caching: Responses that do not change are stored and served again without going to the backend at all.
    • Hiding and protecting the backend: Application servers stay on the internal network and cannot be reached directly from the internet. Malformed or oversized requests can be rejected before they reach the backend.
    • Routing: Several applications are published under a single domain, by path (e.g. /api/) or by subdomain (e.g. panel.example.com).
    • Compression: Text-based responses are sent to the visitor compressed; the application does not have to deal with this.
    • Rate limiting: The number of requests a source can make in a given period is restricted; expensive endpoints such as login and search are protected.
    Cards: what a reverse proxy does; single entry point, TLS termination, load balancing, caching, backend protection, routing, compression, rate limiting : Enlarge
  3. Typical architectures

    • Single application: The reverse proxy and the application are on the same server. The application listens on a local address only (e.g. 127.0.0.1:3000); the reverse proxy is what is exposed to the outside. This is the most common setup and is useful for single-server sites too: the certificate, compression and static files are separated from the application.
    • Several applications: The same reverse proxy looks at the path or the domain of the request and routes it to different applications. The website, the API and the admin panel run as separate processes, but the visitor sees a single site.
    • Several backends: Copies of the same application run on several servers; the reverse proxy spreads requests among them. When one server is taken down for maintenance, the site stays up. The details are in the load balancing guide.
    Diagram: three typical architectures; a single application, several applications by path or subdomain, several load-balanced backends : Enlarge
  4. TLS termination and the real visitor details

    Once a reverse proxy is in between, the backend sees the reverse proxy, not the visitor, at the other end of the connection. To the application, two pieces of information appear to be lost: the visitor's IP address and whether the connection is https. The reverse proxy passes this information on in headers that it adds to the request:

    • X-Forwarded-For: the visitor's IP address (a comma-separated list if there are several proxies in between).
    • X-Forwarded-Proto: the protocol the visitor used (http or https).
    • Host: the domain the visitor asked for.

    The application has to be configured to read these headers; the details are in the "Points to watch" section below.

    Diagram: the visitor connects to the reverse proxy over HTTPS, the reverse proxy forwards to the backend over HTTP on the internal network and adds the Host, X-Forwarded-For and X-Forwarded-Proto headers : Enlarge
  5. How it relates to a CDN and a load balancer

    These three concepts are not rivals but the same idea at different scales:

    • A load balancer is a reverse proxy focused on the job of distribution. A reverse proxy such as Nginx can do load balancing as well; in large setups a separate layer or the hosting provider's managed service is used for it.
    • A CDN (content delivery network) consists of reverse proxies that are spread across different parts of the world and concentrate on caching. The visitor connects to the edge server nearest to them; the edge server requests any content it does not have from your server. Services such as Cloudflare are examples of this kind.

    When they are used together the chain gets longer: visitor → CDN → your own reverse proxy → application. In that case your reverse proxy also sees the CDN, not the visitor, at the other end of the connection; the real address is again read from the headers. For the details, see the CDN guide.

    Diagram: the visitor connects to the CDN, the CDN to the reverse proxy, and the reverse proxy to the application servers : Enlarge

A short Nginx example

The example below spreads requests for example.com across two application servers on the internal network and passes the visitor details on in headers. The upstream block defines the backend servers; the proxy_pass directive sends the request to that group.

Nginx
# Backend servers (internal network)
upstream app_backend {
    server 10.0.0.11:8080;
    server 10.0.0.12:8080;
}

server {
    listen 80;
    server_name example.com www.example.com;

    location / {
        # Pass the request to the backend group
        proxy_pass http://app_backend;

        # The domain the visitor asked for, their real IP address and the protocol
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

If you have a single application, there is no need for an upstream block; writing proxy_pass http://127.0.0.1:3000; is enough. Separating several applications by path and by subdomain looks like this:

Nginx
server {
    listen 80;
    server_name example.com;

    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    # Website
    location / {
        proxy_pass http://127.0.0.1:3000;
    }

    # Requests starting with /api/ go to a separate application
    location /api/ {
        proxy_pass http://127.0.0.1:8080;
    }
}

# Subdomain: the admin panel is a separate application
server {
    listen 80;
    server_name panel.example.com;

    location / {
        proxy_pass http://127.0.0.1:9000;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

The examples are kept bare to show the concept and listen on port 80 only. A real setup needs additions such as HTTPS, timeout settings and WebSocket support: the step-by-step explanation is in the Nginx reverse proxy setup guide, and certificate installation in the guide to HTTPS on Nginx.

Points to watch

The real visitor IP

If the application looks at the other end of the connection, it sees every visitor with the address of the reverse proxy: the logs become meaningless and an IP-based rate limit counts everyone as one person. The solution is to read the X-Forwarded-For header; however, anyone can send this header. If the request comes straight from the internet, the header cannot be trusted. The rule is this: take the header into account only if the connection comes from the address of your own reverse proxy.

PHP
<?php
// Trust the X-Forwarded-For header only if the request comes from your own reverse proxy.
// For a setup with a single reverse proxy; the proxy appends the address it saw to the end of the list.
$guvenilenVekiller = ['10.0.0.5'];

$ip = $_SERVER['REMOTE_ADDR'] ?? '';
if (in_array($ip, $guvenilenVekiller, true) && !empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $adresler = array_map('trim', explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']));
    $aday = end($adresler);
    if (filter_var($aday, FILTER_VALIDATE_IP) !== false) {
        $ip = $aday;
    }
}

// Did the visitor connect to the site over https?
$https = in_array($_SERVER['REMOTE_ADDR'] ?? '', $guvenilenVekiller, true)
    && ($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '') === 'https';

Most application frameworks have a "trusted proxies" setting for this; use that rather than writing it by hand. It is just as important that the backend servers accept connections from the reverse proxy only; otherwise the reverse proxy can be bypassed and a forged header sent.

Protocol information

With TLS termination, the connection that reaches the application is plain HTTP. If the application ignores the X-Forwarded-Proto header, it generates links with http://, does not send "secure" cookies, or keeps redirecting the site to the https address and puts it into an endless loop.

The Host header

By default, Nginx sends the Host header of the request to the backend according to the address in proxy_pass. For the application to see the domain the visitor typed, the line proxy_set_header Host $host; in the example is needed.

Single point of failure

Since all traffic passes through the reverse proxy, the site goes down if it stops, even when the servers behind it are healthy. On small sites this is an acceptable risk; where downtime is expensive, the reverse proxy is set up redundantly as well (two servers with an IP address that can move between them, or the provider's managed load balancer). After changing the configuration, always test it before reloading; one faulty line affects every site.

Timeouts

The reverse proxy does not wait indefinitely for the backend's response. In Nginx, the default of the proxy_read_timeout directive is 60 seconds; if the backend sends no response within that time, the visitor sees a 504 error. If the backend cannot be reached at all, or an invalid response arrives, the error is 502. Solve long-running operations (reports, exports) by running them in the background where possible, not by raising the timeout. The error codes are covered in detail in the guide to 502 and 504 errors.

Upload size

In Nginx, the default of client_max_body_size is 1m (1 megabyte). If your application allows larger file uploads, you need to raise this limit on the reverse proxy too; otherwise the request is rejected with a 413 error before it reaches the application.

When do you need a reverse proxy?

  • If your application is a process running on its own port (such as Node.js, Java, Python or .NET) and you want to publish it on 80/443.
  • If you host several sites or applications on the same server.
  • If you want to manage certificates in one place.
  • If you need to spread traffic across several servers or update without downtime.
  • If you want to separate static files and caching from the application and reduce its load.

For a classic PHP site on shared hosting you do not need to set up a reverse proxy yourself; the hosting provider manages that arrangement. If you manage your own server (a VPS or a physical server), a reverse proxy is a natural part of the setup.

Checklist

  • The backend servers are not exposed directly to the internet; they accept connections from the reverse proxy only.
  • The Host, X-Forwarded-For and X-Forwarded-Proto headers are passed on.
  • The application trusts these headers only on requests that come from the address of the reverse proxy.
  • The real IP address of the visitor appears in the logs.
  • Timeout and upload size limits are set to suit the application's needs.
  • Configuration changes are tested before reloading.
  • It is known what happens when the reverse proxy stops: monitoring and, where needed, a standby are in place.

Frequently asked questions

Is a reverse proxy the same as a load balancer?

Load balancing is one of the jobs of a reverse proxy. Products called load balancers focus on that job; a reverse proxy such as Nginx does TLS termination, caching and routing as well as load balancing.

I have a single server; is a reverse proxy still useful?

Yes. If your application is a process running on its own port, putting a reverse proxy in front of it instead of exposing it directly to the internet gives you a single, proven layer for the certificate, compression, static files and request limits.

Can the connection between the reverse proxy and the backend be unencrypted?

If the two are on the same server or on a closed internal network that belongs only to you, the common practice is to use plain HTTP. If the traffic crosses a network you do not trust, this connection should be encrypted too.

Why does my application see everyone with the same IP address?

Because it is the reverse proxy that opens the connection. Make sure the reverse proxy passes on the X-Forwarded-For header and that the application reads this header only on requests coming from the address of the reverse proxy.

If I use a CDN, do I still need a reverse proxy?

In most cases, yes. A CDN serves content from points close to the visitor; the reverse proxy on your own server is needed for routing to your applications, for the certificate and for limits. The two complement each other.

BYK Yazılım Support Team
This guide is written and regularly reviewed by the BYK Yazılım support team. Last updated: 4 October 2026.

Related guides

Let us talk about your website infrastructure

BYK Yazılım builds corporate websites. Write to us with any questions about your site.

Contact us Our corporate website service