FastCGI is a binary protocol that connects a web server to long-running application processes, so that dynamic requests are handled by workers that stay alive between requests. In servers and web servers, it is the standard interface between front ends such as Nginx, Apache, Caddy or OpenLiteSpeed and language runtimes, most notably PHP-FPM.
FastCGI was designed in the mid-1990s as an improvement on the Common Gateway Interface (CGI). CGI starts a new process for every request, while FastCGI keeps processes running and multiplexes requests over persistent connections, which removes most of the startup cost.
How FastCGI passes a request
In a FastCGI setup, the web server accepts the HTTP connection, handles TLS and static files, and forwards dynamic requests to an application server over a TCP socket or a Unix domain socket. The application process runs the script and returns the response, which the web server sends back to the client.
Communication is split into typed records, each with an 8-byte header that carries the version, record type, request ID and content length. Request metadata travels as name-value parameters, such as SCRIPT_FILENAME, REQUEST_METHOD and QUERY_STRING, which are the same variables CGI uses as environment variables.
The following table lists the main FastCGI record types in the order a typical request uses them.
| Record type | Direction | Content |
|---|---|---|
| FCGI_BEGIN_REQUEST | Web server to application | Role and keep-connection flag |
| FCGI_PARAMS | Web server to application | Request variables as name-value pairs |
| FCGI_STDIN | Web server to application | Request body, such as form or JSON data |
| FCGI_STDOUT | Application to web server | Response headers and body |
| FCGI_STDERR | Application to web server | Error output for the server log |
| FCGI_END_REQUEST | Application to web server | Exit status of the request |
FastCGI compared with other gateway interfaces
FastCGI is one of several ways to connect a web server to application code. The choice depends mostly on the language ecosystem rather than on raw performance.
| Interface | Process model | Typical ecosystem |
|---|---|---|
| CGI | New process per request | Legacy scripts, simple tools |
| FastCGI | Persistent worker pool, binary protocol | PHP-FPM, some Perl and C applications |
| Embedded module | Interpreter inside the web server | Apache mod_php |
| HTTP reverse proxy | Application speaks HTTP itself | Node.js, Go, Java, Python ASGI servers |
| uWSGI or SCGI | Persistent workers, simpler protocols | Python WSGI applications |
| LSAPI | Persistent workers, LiteSpeed protocol | PHP on LiteSpeed and OpenLiteSpeed |
The key advantage over an embedded module such as mod_php is separation. The web server workers stay small and handle static files cheaply, while PHP runs in its own pool with its own user account, memory limits and restart policy.
FastCGI with Nginx and PHP-FPM
The most widespread FastCGI deployment today is Nginx in front of PHP-FPM. Nginx has no built-in PHP interpreter, so every .php request is forwarded with the fastcgi_pass directive to a socket where PHP-FPM listens.
PHP-FPM, the FastCGI Process Manager, maintains pools of PHP workers. Each worker handles one request at a time, so the number of workers sets the maximum number of concurrent PHP requests. The table shows the settings that matter most.
| Setting | Meaning | Practical guidance |
|---|---|---|
| pm | Process manager mode: static, dynamic or ondemand | Static for dedicated servers, ondemand for many small sites |
| pm.max_children | Maximum number of workers | Available memory divided by average worker size |
| pm.start_servers | Workers started at launch in dynamic mode | A small share of max_children |
| pm.max_requests | Requests before a worker is recycled | Several hundred to a few thousand to contain leaks |
| request_terminate_timeout | Hard limit per request | Aligned with the web server timeout |
Sizing pm.max_children is the single most important tuning step. If PHP workers average 60 MB and 3 GB of memory is available for them, about 50 workers is a safe maximum. Setting it far higher risks swapping or the OOM killer under load.
Typical errors and their causes
FastCGI problems usually appear as HTTP 502 or 504 errors from the web server, because the web server is the component that reports a failed upstream. The real cause lies in the application pool or the connection to it.
| Symptom | Likely cause | Fix |
|---|---|---|
| 502 Bad Gateway | PHP-FPM stopped, crashed or wrong socket path | Check the service and the fastcgi_pass target |
| 504 Gateway Timeout | Script runs longer than the read timeout | Optimize the script or align timeouts |
| Max children reached in the log | All workers busy | Raise max_children within memory or fix slow code |
| Primary script unknown | Wrong SCRIPT_FILENAME or document root | Correct the fastcgi_param mapping |
| Permission denied on socket | Socket owner does not match the web server user | Set listen.owner and listen.group |
Security and design considerations
A FastCGI port must never be exposed to the internet. Anyone who can reach it can send arbitrary parameters, including a script path, and execute code. Binding to 127.0.0.1 or to a Unix socket with strict permissions closes this risk.
A classic Nginx misconfiguration passed any URL ending in .php to PHP-FPM, even when the file did not exist. Combined with PHP path handling, this allowed uploaded images to be executed as code. Modern configurations check that the file exists with try_files and limit security.limit_extensions to .php.
On multi-tenant hosts, running one PHP-FPM pool per site under its own system user isolates sites from each other and makes resource use visible per customer, which is how most hosting panels configure FastCGI.
A plain-language summary
A website often needs two kinds of work. Sending a ready-made picture is easy. Building a page from a database takes a program. FastCGI is the agreed way for the web server to hand that harder work to a separate team of program workers.
The workers stay ready all the time instead of being hired anew for each visitor. The web server passes each request along, waits for the finished page, and delivers it. Keeping the workers ready is what makes it fast.
An example from practice
An agency hosts a busy online magazine built on a PHP content management system. The server runs Nginx with PHP-FPM over a Unix socket on a machine with 8 GB of memory. During a traffic spike, visitors start receiving 502 and 504 errors, and the PHP-FPM log reports that the pool reached max_children of 10.
Measurement shows that each PHP worker uses about 70 MB, so the team raises pm.max_children to 60 within the 4.5 GB reserved for PHP, enables OPcache and adds a full-page cache in Nginx for anonymous visitors. Most requests are now served without touching PHP at all, and the remaining ones find free workers. The errors disappear, and average response time falls from over two seconds to under 300 milliseconds.