Home / Servers / SEARXNG VPS

Self-host SearXNG on a VPS that asks for nothing

A metasearch engine that aggregates up to 269 search services and keeps no profile of you. Self-hosting moves the trust from a stranger's instance to your host, so pick a host that never asked who you are.

Deploy a SearXNG VPS from $9.99 / month / 2 GB RAM is plenty

What a private instance changes, and what it does not

Self-hosting solves one problem cleanly and hands you two new ones.
The operator problem moves01

A public instance asks you to trust an operator you cannot see. Your own instance does not delete that trust, it moves it one layer down, to whoever rents you the box.

One instance, one user, one address02

A single-user instance is a single-user proxy. Every query leaves one IP, and that address is billed to an account somewhere. The signup form matters as much as the config file.

Your IP is a datacentre IP03

The real cost of self-hosting search. One operator guide reports empty Google results within ten queries from a busy cloud range, and months of clean running from a quieter one.

Quick start: SearXNG and Valkey with the official compose file

Debian 13, run as root. The searxng-docker repo is archived; this is the current path from the official container docs.
# Sources for every step in this block, and for the numbers quoted on this page:
#   https://docs.searxng.org/admin/installation-docker.html
#   https://raw.githubusercontent.com/searxng/searxng/master/container/docker-compose.yml
#   https://docs.searxng.org/admin/settings/settings_server.html
#   https://docs.searxng.org/admin/searx.limiter.html
#   https://github.com/searxng/searxng/blob/master/searx/settings.yml   (suspended_times)
#   https://github.com/searxng/searxng-docker                          (archived, read-only)
#   https://community.torproject.org/onion-services/setup/             (onion front)

apt update && apt install -y curl ca-certificates openssl
curl -fsSL https://get.docker.com | sh

# 1. Fetch the official compose template and its env file. The compose file
#    defines two services: core (searxng-core) and valkey (searxng-valkey).
mkdir -p /opt/searxng/core-config && cd /opt/searxng
curl -fsSL \
  -O https://raw.githubusercontent.com/searxng/searxng/master/container/docker-compose.yml \
  -O https://raw.githubusercontent.com/searxng/searxng/master/container/.env.example
cp .env.example .env

# 2. With SEARXNG_HOST unset the port is published on every interface.
#    Bind it to loopback and let a reverse proxy terminate TLS.
echo 'SEARXNG_HOST=127.0.0.1' >> .env
echo 'SEARXNG_PORT=8080'      >> .env

# 3. Write settings.yml. The shipped secret_key is the literal string
#    "ultrasecretkey"; leaving it is the most common mistake there is.
cat > core-config/settings.yml <<EOF
use_default_settings: true
general:
  instance_name: "search"
server:
  base_url: "https://search.example.org/"   # your hostname, or your .onion
  secret_key: "$(openssl rand -hex 32)"
  limiter: true             # "Rate limit the number of request on the instance,
                            #  block some bots. The Limiter requires a valkey:
                            #  database." (settings_server.html)
  public_instance: false    # true only if strangers will use it
  image_proxy: true
valkey:
  url: valkey://valkey:6379/0    # docs: hostname "valkey" or "searxng-valkey"
search:
  formats:
    - html                  # add "json" only if you really want an API
EOF

# 4. Start it and check it answers locally.
docker compose up -d
docker compose ps
curl -sI http://127.0.0.1:8080/ | head -1     # expect: HTTP/1.1 200 OK

# 5. Bot detection is tuned in /etc/searxng/limiter.toml inside the container,
#    which is ./core-config/limiter.toml on the host. Do not copy the whole
#    upstream file; override only what you need:
#      https://docs.searxng.org/admin/searx.limiter.html

Rate limits: the part most guides skip

Two limits are at work. One is bots hitting you. The other is engines refusing you.

Why the limiter exists01

Not bandwidth. The docs explain the chain: "SearXNG passes through requests from bots and is thus classified as a bot itself", so blocking bots at your door is the limiter's job.

Three detection methods02

It probes HTTP headers, which is easily bypassed; keeps IP block and pass lists, which is hard to maintain; and rate limits dynamically on request behaviour. Configured in limiter.toml.

Suspension runs on a timer03

search.suspended_times in the upstream settings.yml, linked above, sets the bench: 180 seconds after a rate limit, 3600 after a CAPTCHA, 86400 after a Cloudflare access denial, 1296000 seconds, 15 days, after a Cloudflare CAPTCHA.

Google is the hard case04

The upstream issue "Google is actively blocking SearXNG instances" reports a fresh instance blocked after five consecutive searches, and counted 25 of 91 public instances still serving Google that day.

Retrying is self-harm05

One operator guide: "Once a provider has started challenging your server IP, more retries are often just self-harm." Let the timer run.

Do not enable every engine06

Every engine switched on for its own sake is one more upstream that can start challenging your address, with no matching gain in results.

Reach it without publishing it

A personal search engine does not need a public hostname.
01Keep the port on loopback

The upstream default is bind_address 127.0.0.1. In the container setup that means SEARXNG_HOST=127.0.0.1 in .env; left unset, the compose file publishes on every interface.

02Put it on a WireGuard interface

Run WireGuard on the same VPS and let the proxy listen only on the tunnel address. Your devices reach the instance, everyone else gets a closed port.

03Add an onion front if you want no hostname at all

Two directives in torrc, per the Tor Project onion service guide linked below: HiddenServiceDir /var/lib/tor/searxng/ and HiddenServicePort 80 127.0.0.1:8080. Restart tor, read the hostname file for the .onion address, set it as server.base_url. The other files there are the service keys.

04Decide separately how queries leave

outgoing.using_tor_proxy sends the queries SearXNG makes to engines through Tor, trading speed and a datacentre reputation for an exit node reputation. outgoing.source_ips picks the local address they leave from.

05If it must be public, budget for abuse

Set public_instance and limiter to true and keep Valkey running. Servury offers no DDoS protection on any line, so a public instance needs a scrubbing layer in front.

Which VPS a SearXNG instance actually wants

SearXNG is a metasearch engine: it forwards your query to other search services and merges what comes back. The project calls it "a free internet metasearch engine which aggregates results from up to 269 search services. Users are neither tracked nor profiled" (SearXNG documentation). None of that needs a server. Not wanting to use a stranger's instance is what needs a server.

Self-hosting moves the trust, it does not delete it. On a public instance "the user of the public instance does not know whether their requests are logged, aggregated, and sent or sold to a third party", while on your own "everything is in their control: the source code, logging settings and private data" (Why use a private instance?). What no config file fixes is the layer underneath: the address your queries leave from belongs to a machine somebody rents to you, under a name almost everywhere.

Which is what this host is for. A Servury account is a 32-character credential: no email, no phone, no name, no ID. Payment is Monero, Bitcoin and six other coins processed on Servury's own nodes, cards through Stripe, or cash by mail. servury.com keeps no access logs and runs no analytics. More on the no-KYC VPS page.

The hardware question is easy. There is no index to size a disk for: SearXNG keeps no crawl of its own, and upstream publishes no hardware floor in its installation guide. You are sizing two containers, a Python web service and Valkey. A personal instance is a small job: the two containers idle in a few hundred megabytes, and a 2 GB plan carries them with room for a reverse proxy, WireGuard and a Tor daemon beside it. Blackbox Core, 2 vCPU and 4 GB for $9.99, is more than the job needs, and the standard line covers 8 locations if you would rather sit near yourself than near Montreal.

The egress question is the real one. Engines judge the address requests come from, and hosting ranges start out suspect. Google is actively blocking SearXNG instances, and once an engine starts challenging your address, more retries are often just self-harm. A refusal benches that engine on a timer set under search.suspended_times in the upstream settings.yml, from 180 seconds to 15 days; the published settings page still lists older figures. The one lever you get is outgoing.source_ips, which takes IPv4 or IPv6 addresses in plain or CIDR form (outgoing settings). A Blackbox ships one IPv4 plus a routed /64 to spread across; the standard line is IPv4 only. No honest page promises that this changes an engine's mind.

Where the machine sits matters most when the instance shares a box with something that holds secrets. Blackbox guests run under AMD SEV-SNP with debug disabled, carry no guest agent, and can hand you a CPU-signed attestation report before you type a disk passphrase: see the SEV-SNP VPS page and the measured boot guide. The onion front above is the standard two-directive setup from the Tor Project onion service guide. The everyday companions are a tunnel and a resolver: WireGuard so only your devices reach the instance, Pi-hole for the DNS beside it. A search instance is an ordinary workload under the terms. Cryptocurrency mining beside it is not.

Your search engine, your box, your rules.

No email, no name, no ID. Pay in Monero if you like. Any term from 7 to 365 days.

Deploy a SearXNG VPS

Fair questions

How much RAM does SearXNG need on a VPS?

One sizing guide puts a single user at 1 vCPU and 512 MB of RAM, and there is no index to store because SearXNG does not crawl. The compose file runs two containers, so 2 GB is comfortable and leaves room for a reverse proxy and WireGuard beside them.

Do I need Valkey or Redis?

Only if you turn the limiter on, and you should for anything reachable by more than you. The limiter documentation is blunt about it: "The limiter requires a Valkey database." The official compose file already runs one. Point settings.yml valkey.url at it, or limiter: true does nothing.

Why did my Google results stop working?

Google blocks SearXNG instances, and a datacentre address makes it worse. The upstream bug report says a fresh instance "gets instantly blocked" after five searches in a row, and counted 25 of 91 public instances with a working Google engine. Run engines that are not Google.

Does IPv6 help with engine rate limits?

It gives you addresses to spread requests across, which is not a promise. outgoing.source_ips takes IPv4 or IPv6 addresses, plain or in CIDR form. A Blackbox ships one IPv4 plus a routed /64; the standard line is IPv4 only. Whether an engine counts a whole /64 as one client is up to the engine.

Can I use my instance as a search API for scripts and agents?

SearXNG can emit JSON if you add it to search.formats, a common reason to self-host. Automated query volume is also what makes engines start challenging your address. Running the instance is an ordinary workload under the terms; attacks, spam and cryptocurrency mining are not.

Does Servury see what I search for?

Queries live inside your VM, in whatever logs you keep. Signup asks for no email, no phone, no name and no ID; servury.com keeps no access logs and deletes support messages after 72 hours. Blackbox guests run under AMD SEV-SNP with debug disabled, so the host cannot read guest memory.

Guides on this

Related use cases