SearXNG is a privacy-respecting metasearch engine: it forwards your query to dozens of upstream engines, merges and ranks the results, and keeps no user profile or search history. It replaces Google, Bing or a paid Kagi subscription as your default search, and doubles as a free search API for scripts and AI agents.
Our verdict on SearXNG#
The software is easy and the upstream engines are the problem. SearXNG has no crawler; it scrapes other engines, and those engines have got much better at recognizing a server IP behaving like a bot. Run a private instance on a VPS and the usual outcome is that Google returns nothing parseable within a few queries, Brave and Startpage suspend with too-many-requests or CAPTCHA errors, and DuckDuckGo and a handful of smaller engines keep working. Hosting ranges are scored as automation regardless of how polite your headers or how slow your pace, so you cannot tune your way out. A residential IP behaves far better than a datacenter one, which inverts the usual self-hosting advice. A public instance is a different proposition entirely: it aggregates many people's queries behind one IP, which gets it blocked faster and makes you responsible for whatever strangers search. For a household, run it privately, expect to curate your engine list, and treat the results as good rather than complete.
Who SearXNG is for#
Choose it if
- One household or one person on a home connection, where a residential IP keeps most engines answering.
- Anyone who wants a search box that never builds a profile and never personalizes results.
- Scripts and agents needing a free JSON search endpoint, once you enable the JSON output format.
- People who want bang-style shortcuts and per-category engine selection without a subscription.
Look elsewhere if
- You need Google results specifically and reliably, because a single server IP is exactly what Google blocks.
- You are hosting on a datacenter VPS and will not accept a degraded engine mix.
- You want to run a public instance casually; that carries abuse handling, faster blocking and real legal exposure.
What running it actually looks like#
Two containers: SearXNG itself on 8080, and a Valkey or Redis instance that exists only so the limiter has somewhere to keep counters. The compose template mounts a config directory holding settings.yml, and the first thing to change is secret_key, which the documentation says must not stay at its default. Set base_url to the exact public URL or generated links point at the wrong host. server.method defaults to GET; switching to POST keeps queries out of browser history at the cost of breaking the back button and drag and drop. public_instance is a mode that turns on bot detection and the image proxy together. Behind a reverse proxy, set the trusted proxy networks in limiter.toml or every visitor is rate limited as if they shared one IP. Upgrades are a tag bump; the project uses rolling date-stamped versions rather than semantic releases.
Resource profile#
- Memory
- 150 MB idle, around 350 MB in ordinary use. A handful of uwsgi workers, each a Python process holding the engine definitions; enabling the image proxy raises it noticeably because proxied images pass through the workers.
- CPU and acceleration
- Each search fans out to many engines in parallel and the work is mostly waiting on HTTP, so CPU stays low and the limit is network latency and the slowest engine's timeout.
- Storage growth
- Effectively none. The container is a few hundred megabytes, `settings.yml` is a few kilobytes, and nothing accumulates because nothing is stored.
- Operational load
- 2 of 5, Light. Two containers and one config file, no persistent data, and upgrades are a tag bump. The recurring cost is not the software: it is periodically noticing that an upstream engine has started blocking you and disabling or replacing it in `settings.yml`.
Figures describe a small single-household install and are the working assumptions behind our stack planner. Your numbers will differ with library size, user count and hardware. See methodology.
Data and backup surface#
There is almost nothing to back up, which is the point. settings.yml is the whole instance: enabled engines, the secret key, the base URL, timeouts and UI defaults. limiter.toml holds bot detection tuning and trusted proxy ranges. Copy both, live, into version control and you are done. Valkey holds only ephemeral rate-limit counters and should be excluded; losing it costs nothing beyond briefly permissive rate limiting. There are no user accounts, no search history and no index, because preferences live in the visitor's own cookie or in a shareable settings URL. That also means a restore is instant and a rebuild from scratch is a docker compose up plus one file.
Derived backup shape
File copy. Copy the config and data directories. Safe while running for anything that writes atomically.
Traps and surprises#
Upstream engines block single-IP instances
The most common failure is not SearXNG breaking, it is Google returning a too-many-requests exception after a handful of searches from a fresh instance. Datacenter address ranges are scored as automation and some engines serve a CAPTCHA to every request from them regardless of pacing. There is no configuration that fixes this. You disable the engines that block you, lean on the ones that do not, and accept a thinner result mix.
429 has two completely different causes
A 429 shown to your browser is your own limiter deciding you look like a bot. An engine refusing your server appears differently: the results page loads with sections missing or an engine marked as suspended. People spend hours tuning the limiter when the real problem is upstream, or the reverse. Read the engine status on the preferences page before you touch limiter.toml.
The limiter needs Valkey and trusted proxy config
Setting limiter: true without a reachable Valkey means the limiter cannot function. Getting it working behind a reverse proxy without listing your proxy in the trusted networks in limiter.toml is worse: every request appears to come from the proxy's address, so all of your users share one bucket and the whole instance rate limits itself after a few searches.
JSON output is off by default
The obvious use as a search API for scripts or an AI agent does not work out of the box, because only the HTML format is enabled. You add json to the search.formats list in settings.yml and restart. Do this and then leave the instance reachable from the internet and you have published an open, unauthenticated search API that others will find and use through your IP.
A public instance is a different commitment
Running one for strangers concentrates many people's queries behind your single address, which accelerates every blocking problem above, and it makes your IP the origin of whatever anyone searches for. The project provides a public_instance mode with bot detection and the image proxy for exactly this reason. If you are not prepared to handle abuse reports, keep it private and behind an auth proxy.
Specifications#
- Category
- Local AI and private search
- Licence
- AGPL-3.0-or-later (Copyleft)
- Written in
- Python
- First release
- 2021
- Maturity
- Stable
- Datastore
- None; Valkey or Redis only if you enable the limiter
- Default ports
8080- Ships as
- docker, native install with uwsgi, helm chart
- arm64 builds
- Yes
- Identity
- Not applicable. No accounts and no login; preferences are stored client side in a cookie or a settings URL, so access control means an auth proxy in front.
- Replaces
- Google Search, Bing, Kagi, DuckDuckGo
- Project site
- docs.searxng.org
- Source
- github.com/searxng/searxng
- Documentation
- docs.searxng.org/admin/installation-docker.html
Alternatives to SearXNG#
Everything else in local ai and private search, closest in operational weight first.
| Tool | Ops load | Idle RAM | Licence |
|---|---|---|---|
| Ollama | 2, Light | 150 MB | MIT |
| Open WebUI | 2, Light | 600 MB | Open WebUI License (BSD-3-Clause plus a branding clause) |
| LocalAI | 3, Moderate | 300 MB | MIT |
Where SearXNG comes up elsewhere#
Head to head
Migration guides
Sources#
Facts on this page were checked against the project's own material. Where a number is our own estimate rather than a published figure, the text says so.
Published . Last reviewed . Found something out of date? Tell us and we will fix it and log the change.