What the web announces about itself: server and x-powered-by headers
Of the 214,006,060 domains that sent a Server, CSP or X-Powered-By header in the September 2026 census, the most common Server value is cloudflare, on 44,468,182 domains, 20.78% of that total, seen in 872 TLDs. That count takes in all the domains that answered a request, with no sampling from a list of popular sites. The tables below give the top ten values for each header, ordered by domain count, and the rest of the page is about what a header line can’t prove.
The two tables
Both tables are copied as the census sheet carries them: rank, the string as it was sent, the number of domains sending it, that number as a share of the 214,006,060 header-sending domains, and how many TLDs the value turned up in.
Server header, top ten values:
| rank | value | domains | share of http_headers_present | TLDs |
|---|---|---|---|---|
| 1 | cloudflare | 44,468,182 | 20.78% | 872 |
| 2 | nginx | 40,332,427 | 18.85% | 976 |
| 3 | apache | 36,527,330 | 17.07% | 929 |
| 4 | openresty | 10,724,227 | 5.01% | 797 |
| 5 | litespeed | 10,509,871 | 4.91% | 793 |
| 6 | squarespace | 9,354,618 | 4.37% | 723 |
| 7 | pepyaka | 7,775,040 | 3.63% | 746 |
| 8 | hcdn | 6,735,793 | 3.15% | 729 |
| 9 | namecheap-nginx | 5,150,129 | 2.41% | 542 |
| 10 | vercel | 4,269,699 | 2.00% | 792 |
X-Powered-By header, top ten values:
| rank | value | domains | share of http_headers_present | TLDs |
|---|---|---|---|---|
| 1 | asp.net | 2,494,768 | 1.17% | 796 |
| 2 | php/8.3.33 | 2,239,623 | 1.05% | 752 |
| 3 | php/7.4.33 | 2,230,402 | 1.04% | 752 |
| 4 | php/8.2.33 | 2,129,553 | 1.00% | 746 |
| 5 | php/8.1.34 | 1,318,371 | 0.62% | 739 |
| 6 | plesklin | 1,277,748 | 0.60% | 763 |
| 7 | next.js | 1,262,173 | 0.59% | 774 |
| 8 | express | 801,859 | 0.37% | 762 |
| 9 | php/8.3.30 | 573,068 | 0.27% | 650 |
| 10 | hostingerwebsitebuilder | 568,475 | 0.27% | 517 |
The shares in the second table are small because most domains don’t send an X-Powered-By header at all. The denominator is the same 214,006,060 for both tables, so the two share columns can be read side by side.
What the two lines are
A Server value and an X-Powered-By value are strings the responding server chooses to send. They sit in the response headers beside the content type and the cache directives, ahead of the first byte of page content, and anyone who makes one request can read them. No browser needs either one; a page with both missing renders the same as a page with both present. They belong to the same family of response headers as the ones that control framing, sniffing and referrers, with one difference: those headers instruct the browser, and these two describe the sender.
A response that sends both looks like this, trimmed to the lines that matter:
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Cache-Control: max-age=600
Server: nginx
X-Powered-By: PHP/8.3.33
To see what your own domain sends, make one request and read the headers back:
curl -sI https://example.com
Swap in your domain. If a Server line or an X-Powered-By line comes back, that’s the string the census counted for you.
Each row is a floor
The census counted a value where it sat inside a TLD’s top 40, and that method sets what the tables can say. The listed Server total is 206,079,504 domains (96.30% of http_headers_present) and the listed X-Powered-By total is 22,325,500 (10.43%). A value that was common in one country’s TLD and rare elsewhere was counted where it made that TLD’s top 40 and dropped where it didn’t. So each row is a floor: the true count for any value is at least the number printed, and the long tail of rare strings sits outside the listed totals altogether.
For the values at the top of the Server table the floor and the true count are close, because cloudflare, nginx and apache make the top 40 in nearly every TLD. For a value that appears in a few dozen TLDs the gap could be wider. The TLDs column is there so you can judge which case you’re reading.
Whatever answered first is what got counted
A Server value describes whatever answered the request. On a lot of domains that’s a CDN, a reverse proxy or a load balancer, and the software running the application sits behind it, unnamed in the response. The top row of the Server table is a CDN, which on its own tells you these are the strings the web sends, and the software running behind them is often something else.
The table carries its own evidence for this. Ranks 26 to 37 of the Server values are internal instance hostnames of the form ip-100-74-4-123.eu-west-2.compute.internal, each counted as its own value, the largest at 439,897 domains (0.21%, 380 TLDs). Twelve of the top 40 Server strings are hostnames a machine gave itself, and a hostname says nothing about which product answered.
Which front door answers is settled before the request reaches any server. The DNS record for the name points at either the proxy or the origin, and the Server line you read belongs to whichever one that record chose.
Blank, renamed or left at the default
An operator can strip the Server value or replace it with a word of their own, and plenty leave it at whatever the package shipped with. When it’s absent, something still answered the request, so absence says nothing about whether a server is running. When it’s present it can be wrong in both directions: a proxy may have overwritten it with its own name, or a default nobody edited may describe a product that was swapped out underneath.
So when you read Server: nginx on a domain, what you’ve learned is that a string saying nginx was sent. That string may have come from the origin or from a proxy in front of it, and the census counts it either way.
The prefix and the version string
Some platforms send a powered-by header without the x- prefix, and a query written only for the x- form misses them. The sheet counts the x-powered-by field and carries nothing on the unprefixed form, so this page can’t put a number on it.
Many values in the table carry an exact release number, and some carry two products in one string: php/8.3.33, plesklin is counted on 336,141 domains (0.16%, 612 TLDs) as its own value, separate from php/8.3.33 on its own. A value is sometimes a component and sometimes a whole stack. The table counts the string as sent, so the same PHP release turns up in more than one row depending on what was sent beside it.
A release number that’s present may be stale or may have come from a proxy, and one that’s absent tells you nothing about what’s installed or how current it is. Nothing on the wire checks either case; the server writes the header about itself and the client takes it as sent.
What one request tells a stranger
Someone who wants to know what’s running on a domain that sends no version string has to probe for it, sending requests and reading how the application misbehaves. When X-Powered-By carries the release number, the first request answers, and they can match that number against a public list of known issues in seconds.
The counts put a number on how many domains give that answer up front. 22,325,500 domains sit inside the listed X-Powered-By values, 10.43% of the 214,006,060 domains that sent a Server, CSP or X-Powered-By header, and most of the values in that table carry a release number.
Removing the header changes what’s announced and leaves what’s running untouched, so it’s tidying, and patching stays a separate job. A stack with the header off is the same stack on the same release; the difference is that a stranger now has to work for the information the first response used to hand over. That’s a small change with a low cost, and it’s the one an auditor will flag if you skip it.
The line that turns it off
Each of these is a one-line change in a config file you already have. Reload or restart after editing, then run the curl line again.
# nginx (nginx.conf, inside the http block)
server_tokens off;
# Apache (httpd.conf or apache2.conf)
ServerTokens Prod
ServerSignature Off
# PHP (php.ini)
expose_php = Off
# Express (where the app is created)
app.disable('x-powered-by');
# IIS (web.config, under <system.webServer><httpProtocol><customHeaders>)
<remove name="X-Powered-By" />
On nginx and Apache these lines trim the release number from the Server value and leave the product name in place; stripping the header entirely is a job for the proxy or a module. The Express and IIS lines remove X-Powered-By outright, and expose_php = Off stops PHP adding its own.
These settings sit in the same block where you’d set Strict-Transport-Security, so if you’re in the file anyway, both changes go in together. A reverse proxy or CDN in front of the origin may still add or keep its own Server value, because it writes its headers after yours. Check the curl output against the front door, since that’s the response the census counted and the one a stranger reads.
Figures as of 5 September 2026, from the September 2026 edition of the defaults.exposed census. Census numbers move every month; the current values are on the census data page.