GoToSocial: A Lightweight Fediverse Server You Can Actually Run on a Raspberry Pi
Mastodon is the default answer when people ask about self-hosting a fediverse server. But Mastodon is also a resource hog — it wants multiple services (web, streaming, sidekiq), a PostgreSQL database, Redis, and ideally Elasticsearch. On a small VPS or Raspberry Pi, running Mastodon means your server does little else.
Photo by Mike Setchell on Unsplash
GoToSocial is a lightweight, single-binary ActivityPub server written in Go. It federates with Mastodon, Pleroma, Akkoma, Misskey, Pixelfed, and everything else that speaks ActivityPub — but it runs in a fraction of the resources. If you want a fediverse presence without dedicating an entire server to it, GoToSocial is the answer.
Why GoToSocial Instead of Mastodon?
GoToSocial is not trying to replace Mastodon for large public instances with thousands of users. It targets a different use case: personal instances, small communities, and resource-constrained environments.
The core philosophy is different too. GoToSocial is designed as a server-only application. It provides the ActivityPub backend and API, but it does not ship its own web frontend. You use a Mastodon-compatible client (like Tusky, Megalodon, Elk, or Pinafore) to interact with your account. This keeps the server lean and lets you pick the client you prefer.
Resource Comparison
| Resource | GoToSocial | Mastodon | Pleroma/Akkoma |
|---|---|---|---|
| RAM (idle) | ~50-100 MB | ~1-2 GB | ~300-500 MB |
| CPU cores | 1 | 2-4 recommended | 1-2 |
| Disk (application) | ~30 MB | ~500 MB+ | ~200 MB |
| Services required | 1 (single binary) | 4+ (web, streaming, sidekiq, etc.) | 2 (main + database) |
| Database | SQLite or PostgreSQL | PostgreSQL only | PostgreSQL only |
| Background jobs | Built-in | Sidekiq (separate process) | Built-in (Oban) |
| Redis/Valkey | Not needed | Required | Not needed |
| Elasticsearch | Not needed | Optional but recommended | Not needed |
GoToSocial's ability to run on SQLite means you can skip PostgreSQL entirely for small instances. A personal instance serving one to five users runs comfortably on a 512 MB VPS or a Raspberry Pi 3.
What GoToSocial Can and Cannot Do
Before deploying, understand the trade-offs.
What works well:
- Posting, replying, boosting, favoriting
- Following and interacting with users on any ActivityPub server
- Media attachments (images, video, audio)
- Content warnings and sensitive media flags
- Custom emoji
- Hashtags and mentions
- Account migration (move followers to/from other instances)
- RSS feeds for public profiles
- Blocklists and allowlists for federation control
- HTTP signatures for secure federation
- Markdown formatting in posts
What is missing or limited (as of early 2026):
- No built-in web frontend (use Mastodon-compatible clients)
- No polls (planned but not implemented)
- No full-text search (only hashtag search)
- No trending topics or explore page
- No announcements feature
- Smaller plugin/integration ecosystem than Mastodon
- Less battle-tested at scale (not designed for thousands of users)
For a personal or small-group instance, these limitations rarely matter. If you need polls and trending topics for a large community, Mastodon is the better choice.
Deploying GoToSocial with Docker
GoToSocial's Docker deployment is refreshingly simple — a single container with an optional database.
Basic Setup with SQLite
Create a project directory and the following docker-compose.yml:
version: "3.8"
services:
gotosocial:
image: superseriousbusiness/gotosocial:latest
container_name: gotosocial
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- ./data:/gotosocial/storage
- ./config.yaml:/gotosocial/config.yaml
environment:
GTS_HOST: social.yourdomain.com
GTS_DB_TYPE: sqlite
GTS_DB_ADDRESS: /gotosocial/storage/sqlite.db
GTS_LETSENCRYPT_ENABLED: "false"
GTS_ACCOUNTS_REGISTRATION_OPEN: "false"
GTS_TRUSTED_PROXIES:
- "127.0.0.1/32"
- "172.16.0.0/12"
Production Setup with PostgreSQL and Reverse Proxy
For better performance with multiple users or if you want proper database tooling:
version: "3.8"
services:
gotosocial:
image: superseriousbusiness/gotosocial:latest
container_name: gotosocial
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
networks:
- gotosocial
- proxy
volumes:
- gotosocial-storage:/gotosocial/storage
environment:
GTS_HOST: social.yourdomain.com
GTS_PROTOCOL: https
GTS_PORT: 8080
GTS_DB_TYPE: postgres
GTS_DB_ADDRESS: postgres
GTS_DB_PORT: 5432
GTS_DB_USER: gotosocial
GTS_DB_PASSWORD: ${POSTGRES_PASSWORD}
GTS_DB_DATABASE: gotosocial
GTS_LETSENCRYPT_ENABLED: "false"
GTS_ACCOUNTS_REGISTRATION_OPEN: "false"
GTS_MEDIA_REMOTE_CACHE_DAYS: 7
GTS_TRUSTED_PROXIES:
- "127.0.0.1/32"
- "172.16.0.0/12"
labels:
- "traefik.enable=true"
- "traefik.http.routers.gotosocial.rule=Host(`social.yourdomain.com`)"
- "traefik.http.routers.gotosocial.entrypoints=websecure"
- "traefik.http.routers.gotosocial.tls.certresolver=letsencrypt"
- "traefik.http.services.gotosocial.loadbalancer.server.port=8080"
postgres:
image: postgres:16-alpine
container_name: gotosocial-db
restart: unless-stopped
networks:
- gotosocial
volumes:
- gotosocial-db:/var/lib/postgresql/data
environment:
POSTGRES_USER: gotosocial
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: gotosocial
healthcheck:
test: ["CMD-SHELL", "pg_isready -U gotosocial"]
interval: 10s
timeout: 5s
retries: 5
volumes:
gotosocial-storage:
gotosocial-db:
networks:
gotosocial:
proxy:
external: true
Create a .env file:
POSTGRES_PASSWORD=your-secure-password-here
Start the stack:
docker compose up -d
Like what you're reading? Subscribe to Self-Hosted Weekly — free weekly guides in your inbox.
Creating Your Account
GoToSocial does not have a web-based registration flow. You create accounts via the CLI:
docker exec -it gotosocial /gotosocial/gotosocial \
admin account create \
--username yourname \
--email [email protected] \
--password your-secure-password
To promote the account to admin:
docker exec -it gotosocial /gotosocial/gotosocial \
admin account promote --username yourname
Then log in from any Mastodon-compatible client by entering social.yourdomain.com as the instance URL.
Choosing a Client
Since GoToSocial does not have its own web interface, you need a Mastodon-compatible client. The GoToSocial API is largely compatible with the Mastodon API, so most clients work.
Mobile:
- Tusky (Android) — the most popular Mastodon client, works well with GoToSocial
- Megalodon (Android) — fork of the official Mastodon app with extra features
- Ice Cubes (iOS) — modern, fast, well-maintained
- Ivory (iOS) — polished, from the makers of Tweetbot
Web:
- Elk — modern web client with a clean interface (self-hostable)
- Pinafore (now Semaphore) — lightweight single-page web client
- Phanpy — another excellent lightweight web client
Desktop:
- Whalebird — cross-platform Electron-based client
- Toot (macOS) — native Mac app
Federation and DNS Setup
For federation to work correctly, your domain needs proper DNS and your reverse proxy needs to handle WebFinger requests.
DNS Records
Point your domain to your server:
social.yourdomain.com A YOUR_SERVER_IP
social.yourdomain.com AAAA YOUR_IPV6_ADDRESS
WebFinger
ActivityPub uses WebFinger to discover users. When someone searches for @[email protected], their server queries https://social.yourdomain.com/.well-known/webfinger. GoToSocial handles this automatically — just make sure your reverse proxy passes requests to /.well-known/ through to GoToSocial.
If you want to use your apex domain in handles (like @[email protected] instead of @[email protected]), you can set up WebFinger delegation. Add a redirect on your main domain:
# On yourdomain.com's web server
location /.well-known/webfinger {
return 301 https://social.yourdomain.com$request_uri;
}
And set GTS_ACCOUNT_DOMAIN=yourdomain.com in your GoToSocial config (keeping GTS_HOST=social.yourdomain.com).
Storage Management
GoToSocial caches media from remote instances — profile pictures, post attachments, and custom emoji from every account your users interact with. This cache grows over time.
Control it with these environment variables:
# Clean up cached remote media older than 7 days
GTS_MEDIA_REMOTE_CACHE_DAYS: 7
# Maximum size for local media uploads (in bytes)
GTS_MEDIA_IMAGE_MAX_SIZE: 10485760 # 10 MB
GTS_MEDIA_VIDEO_MAX_SIZE: 41943040 # 40 MB
GoToSocial also runs a background media cleaner that prunes expired remote media automatically. For a single-user instance with moderate following, expect storage to stabilize around 1-5 GB with a 7-day cache.
You can also run a manual cleanup:
docker exec -it gotosocial /gotosocial/gotosocial \
admin media prune --dry-run
Remove --dry-run to actually delete files.
Migrating From Mastodon
GoToSocial supports the ActivityPub account migration protocol. You can move your followers from a Mastodon account to GoToSocial (and vice versa).
- On your GoToSocial account, go to settings and add your old Mastodon account as an alias
- On your Mastodon account, go to Settings > Account > Move to a different account
- Enter your GoToSocial account address
- Confirm the migration
Your followers on other instances will be automatically redirected to follow your new GoToSocial account. Note that posts do not migrate — only followers. Export your posts from Mastodon separately if you want an archive.
Backups
For SQLite deployments, back up the data directory:
# Stop to ensure consistency (or use SQLite online backup)
docker compose stop gotosocial
cp -r ./data ./data-backup-$(date +%Y%m%d)
docker compose start gotosocial
For PostgreSQL deployments:
docker exec gotosocial-db pg_dump -U gotosocial gotosocial > backup-$(date +%Y%m%d).sql
# Also back up the storage volume for media files
GoToSocial vs Other Lightweight Alternatives
| Feature | GoToSocial | Akkoma | Misskey/Firefish | Mastodon |
|---|---|---|---|---|
| Language | Go | Elixir | TypeScript | Ruby |
| RAM usage | ~50-100 MB | ~300-500 MB | ~500 MB+ | ~1-2 GB |
| SQLite support | Yes | No | No | No |
| Built-in web UI | No | Yes | Yes | Yes |
| Polls | No | Yes | Yes | Yes |
| Reactions | No | Yes (emoji reactions) | Yes | No |
| Markdown posts | Yes | Yes (MFM) | Yes (MFM) | No |
| Quote posts | No | Yes | Yes | No |
| Bubble timeline | No | Yes | No | No |
| Target audience | Personal/small | Small-medium | Small-medium | Any size |
Security Considerations
GoToSocial takes a conservative approach to security:
- Registration closed by default — you must explicitly open registration or create accounts via CLI
- HTTP signatures — all federation traffic is signed and verified
- Blocklists — import and export domain blocklists to control federation
- Allowlists — optionally restrict federation to only approved instances
- Rate limiting — built-in rate limiting for API and federation endpoints
For a personal instance, keep registration closed and create accounts manually. This eliminates the entire category of spam account problems that plague open Mastodon instances.
Is GoToSocial Right for You?
Choose GoToSocial if:
- You want a personal or small-group fediverse presence
- You are running on limited hardware (Raspberry Pi, small VPS)
- You prefer using your own choice of Mastodon client
- You want minimal operational overhead
- You do not need polls, trending, or a built-in web interface
Choose Mastodon instead if:
- You are running a public instance for many users
- You need a built-in web interface
- You want polls and the full feature set
- You have the server resources to spare
Choose Akkoma if:
- You want something between GoToSocial and Mastodon in weight
- You want emoji reactions and quote posts
- You want a built-in web interface but lighter than Mastodon
GoToSocial is still pre-1.0, but it is actively developed and already stable enough for daily use. The project has been gaining significant traction in the self-hosting community precisely because it solves the "I want to be on the fediverse without running a heavy stack" problem cleanly and reliably.
