# Nextcloud best practices

Reliable Nextcloud performance depends on the right cache layers, a tuned PHP runtime, and healthy background jobs. On TurboStack, most of this is configured when you deploy a `nextcloud` app, so your main effort is keeping caching healthy and following Nextcloud's own production guidance. This page covers what the platform configures and the optimizations to layer on top.

## What TurboStack configures for you

When you deploy Nextcloud, TurboStack provisions a working, production-shaped stack:

- **Nginx vhost tuned for Nextcloud** - the document root is set to `public_html`. Standard Nextcloud rewrites and `location` blocks are in place: front-controller routing through `index.php`, `.well-known` redirects for CalDAV/CardDAV (calendar and contacts), and `deny` rules for `data`, `config`, `lib`, `3rdparty`, `occ`, and similar paths. Security headers are added, `X-Powered-By` is hidden, and static assets are served with long-lived `Cache-Control`.
- **PHP-FPM backend per site** - PHP requests are passed to a dedicated FastCGI pool, with `fastcgi_request_buffering off` and `HTTPS on` set so large uploads and DAV requests behave correctly. DAV is short for Distributed Authoring and Versioning, the WebDAV protocol behind CalDAV and CardDAV.
- **Redis (required)** - installed and configured in `config.php` over a unix socket (`/var/run/redis/redis.sock`). It is configured for transactional file locking (`memcache.locking = \OC\Memcache\Redis`), with APCu (`memcache.local = \OC\Memcache\APCu`) as the local memory cache.
- **config.php essentials** - `trusted_domains` is populated with your server name, FQDN, and host IP. `overwrite.cli.url`, `mysql.utf8mb4`, and the `production` updater channel are set via `occ config:system:set`.
- **Database** - a dedicated MySQL/MariaDB (or PostgreSQL) database and user are created and Nextcloud is installed against it with `occ maintenance:install`.
- **Transport Layer Security (TLS) and large uploads** - TLS is provisioned (Let's Encrypt or your own certificate). The upload ceiling is driven by `nextcloud_max_upload_size` (default `512m`), which also sets the PHP and web-server limits.
- **Hardened data permissions** - the data directory is created outside the web root, owned by the system user, with directories at `0750` and files at `0640`.

## Recommended optimizations

- **Keep Redis healthy** - Redis is mandatory for transactional file locking and the memory cache. Confirm it is running as a [service](../../platform/hosts/services.md) and monitor its memory so locks do not revert to the database.
- **Use system cron for background jobs** - set the background job mode to **Cron** (`occ background:job:mode cron`). A system scheduler then runs `cron.php` every 5 minutes, which is faster and more reliable than the AJAX (Asynchronous JavaScript and XML) or webcron modes (`nextcloud_background_cron`).
- **OPcache** - the PHP runtime ships with OPcache; keep it enabled (with a generous `interned_strings_buffer` and `memory_consumption`) so compiled PHP is reused across requests.
- **Add full-text search (optional)** - for large libraries, install the Full Text Search apps backed by Elasticsearch/OpenSearch so document search stays fast.
- **Raise upload limits deliberately** - increase `nextcloud_max_upload_size` (and the matching PHP `upload_max_filesize`/`post_max_size`) when users sync large files; avoid setting it far higher than needed.
- **Run "Add missing indices"** - after upgrades, run `occ db:add-missing-indices` and clear the admin overview warnings to keep queries efficient.
- **Front media with a Content Delivery Network (CDN)** - serve static assets through an HTTP cache/CDN to cut origin load and improve global latency.

## Sizing and scaling

Defaults are auto-tuned to the host, so do not pre-emptively raise them. Override sizing variables only with measured evidence (slow queries, cache evictions, swap):

| Variable | Tune when |
| --- | --- |
| `mysql_innodb_size` | The MySQL working set no longer fits in the buffer pool |
| `redis_memory` | Redis evicts keys or locking contention appears under load |
| `elasticsearch_heap_size` | Full-text search is enabled and indexing pressures memory |

See [Performance tuning](../../concepts/performance-tuning.md) for the full method: measure, change one variable, re-measure.

## Stability

- **Back up regularly** - keep automated [Backups](../../platform/hosts/backups.md) of the database and the data directory; test a restore before you need one.
- **Watch the host** - monitor the [Health](../../platform/hosts/health.md) tab for CPU, memory, disk, and service alerts. A full data disk takes Nextcloud offline.
- **Stay current** - keep Nextcloud, its apps and the PHP runtime on supported versions; apply upgrades through the built-in updater (pinned to the `production` channel) during quiet windows.
- **Test on a staging clone** - validate major upgrades and app changes on a copy of the host before touching production.

## Related

- [Deploy Nextcloud](deploy.md)
- [Troubleshooting Nextcloud](troubleshooting.md)
- [Services](../../platform/hosts/services.md)
- [Performance tuning](../../concepts/performance-tuning.md)
