Add Tailscale to an application and it joins your own tailnet as a device, making every database, cache and other service in that application reachable from your laptop. No public port, no tunnel to keep alive, and access is governed entirely by your own tailnet rules.
Before: Reaching a production database from your machine meant exposing a port or setting up a tunnel yourself. After: Add Tailscale once and connect straight to your databases from any device on your tailnet.
Third-party APIs and managed databases that only accept traffic from an allowlisted IP are now within reach. Route specific outbound connections through an exit node in your own tailnet and the other side always sees the same address.
Before: Your application had no fixed outbound address, so it could not be added to someone else's IP allowlist. After: List the services you want to route, and they leave through an IP you control.
Typesense joins Meilisearch under the Search category when you add a service. It is a fast, typo-tolerant search engine that works as a Laravel Scout backend out of the box, and comes with a generated API key and persistent storage.
A new AMQProxy service under the Queue category keeps broker connections open and reuses them, so PHP stops doing a full handshake on every request that publishes a message. On a distant broker this can cut a publish from around 500ms to around 10ms, and on a nearby one it replaces thousands of short-lived connections per minute with a small, steady pool.
Before: Every request that published a message opened a fresh connection, handshaked, sent one message and threw the connection away. After: Connections are pooled and reused, and your broker sees a flat, low connection count.
Services you add now have an Instances field, so you can run several copies to share the load and stay available while one restarts. Services that only need a little memory can also be sized down to 125MB or 250MB, below the previous half-gigabyte floor.
The optional settings on services like Chrome Headless, Gotenberg, Meilisearch and Typesense used to be locked in at creation. You can now edit them from the service menu under Edit resources, in a new Service configuration section.
Before: Getting a setting wrong meant deleting the service and adding it again. After: Edit any configurable setting in place, with validation and clear descriptions.
When your application or one of its services failed its health check and got restarted, the platform recovered automatically and every trace of it was gone by the time you looked. Those restarts are now recorded and kept for 7 days under Debug history in the Debug tab.
Before: A restart healed itself and left nothing behind to explain what happened. After: See exactly what restarted, when, whether it cost you any uptime, and what your application printed just before it went down.
Offsite backups now tell you when something goes wrong. If a nightly backup fails and its retries are exhausted, the team owner gets an email with a link straight to the application's backups page. Successful backups and runs that recover on a retry never trigger it.
Passwords, tokens and API keys returned through the API or through an AI assistant connected to Ploi Cloud are now masked. Credentials embedded in connection strings are masked too, and secrets no longer slip out through error messages. When you are working with an AI assistant it will only show you a real secret when you explicitly ask for it.
Opening debug access on a service now shows a ready-to-copy connection URL for Meilisearch, Typesense, ClickHouse, Gotenberg, Chrome Headless and MinIO, along with that service's API keys and passwords behind a reveal button. Turning debug access on or off also updates by itself instead of needing a page refresh.
When object storage cannot be created, the exact reason now appears under the error status instead of a generic failure message, for example that creation is temporarily disabled in a region and you should pick another one.
Services that take a while to come up were being restarted before they had finished starting. They now get a proper grace period, and services that do not speak HTTP are checked in a way that suits them.
Two new pages cover the ways to drive Ploi Cloud without the dashboard. The MCP server page walks through connecting Claude Code, Cursor, Windsurf or any MCP client in one command and one browser authorization. The CLI page covers installing the open-source ploicloud CLI with Homebrew or a direct download and scripting anything the platform can do. The AI page now ties the MCP server, the CLI and the API together.
Marketing, documentation, blog and changelog pages were loading the entire dashboard bundle they never used. They now ship their own minimal bundle instead, roughly 89% less JavaScript per page, so documentation and marketing pages become interactive noticeably faster.
If your Statamic site has ever quietly stopped committing content back to your repository, it is usually an expired provider token. A new guide walks you through setting up a per-repository SSH deploy key that does not expire, covering GitHub, GitLab and the Bitbucket alternative.
The guide on build-time versus runtime variables has been rewritten to match how the platform actually works. There is one list of environment secrets and every entry is available both while your image is built and while your application runs. It also explains why credentials from services like MySQL or Redis are only available at runtime, and what the harmless APP_KEY warning in your build log means.
Emails from Ploi Cloud are now marked as automated, so deploy notifications, invoices and support replies no longer set off automatic out-of-office responses.
On newer applications, changes to SSL protocols and ciphers, security headers, basic authentication, maximum upload size and request timeouts only took effect on the very first deploy. Later edits saved fine and the deploy reported success, but your live site kept serving the old settings. Every one of these now applies on your next deploy.
Setting SSL protocols to "TLSv1.2 TLSv1.3" required TLS 1.3 for every connection, which could lock out older browsers, API clients and webhook senders. The lowest protocol you list is now the minimum, so listing TLS 1.2 keeps it enabled.
Turning on security headers or clicking "Reset to defaults" filled the cipher list with three ciphers the platform does not support, so saving failed with an "unsupported SSL cipher" error. Those ciphers were removed from the defaults, and your unsaved edits are no longer wiped by the page refreshing in the background while your application is deploying.
With Cloudflare's SSL mode set to Full (strict), certificate issuance for a custom domain could deadlock and visitors saw Cloudflare error 526. Certificate validation is now exempt from the HTTPS redirect, so the first certificate is issued normally and all other traffic still redirects to HTTPS.
A change on Bitbucket's side broke repository listing, leaving the picker empty after you connected a Bitbucket account. Repositories from every workspace you belong to are listed again, sorted by most recently updated, and accounts with more than 100 repositories now see all of them.
Backups to Cloudflare R2 failed on every upload and left the bucket empty. Storage providers are now detected correctly from your endpoint, database dumps upload in a form R2 accepts, and an endpoint accidentally entered with the bucket name appended no longer files your backups in the wrong place. AWS S3, MinIO, Wasabi, Backblaze, DigitalOcean Spaces, Scaleway and Google Cloud Storage benefit from the same fixes.
A backup whose database dump or upload failed still finished in a successful state, so the backups tab showed a completed backup while nothing had actually been stored. Any failing step now fails the whole backup, and transient errors are retried automatically before that happens.
Saving offsite storage only checked that the credentials could read, so read-only keys such as a Cloudflare R2 "Object Read only" token were accepted and then failed silently every night. Saving now writes and removes a test file, and tells you plainly when the credentials cannot write. Changing the access key ID without entering a matching secret is also blocked instead of quietly keeping the old secret.
Databases running PostgreSQL 18 were skipped by offsite backups because the backup tooling only shipped clients up to version 17. PostgreSQL 13 through 18 are now all covered.
The Chrome Headless service pointed at browser versions that no longer exist, so it could never start. The version list has been corrected and existing services were moved to a working version automatically, with nothing for you to do.
Statamic sites using Git sync had their working copy force-reset to the remote on every check, which destroyed content commits that had not been pushed yet. The sync now only fast-forwards when it is safe to do so and leaves your content alone otherwise. Sync failures caused by an expired token or a network problem are also written to your logs instead of being swallowed.
The Meilisearch master key was returned in plain text by the service environment endpoint and through AI assistant tools. It is now masked along with every other variable ending in _KEY. You can still read the key yourself from the service's debug dialog in the panel.
The schedule runner could drift out of sync with the clock and, every so often, skip a whole minute, so a task due in that minute simply never ran with no error to show for it. It now runs exactly on the minute, every minute. Your application picks this up on its next deployment.
Removing a wildcard domain always said it succeeded, even when the certificate was left behind. Removal is now verified, and if it cannot be completed the domain stays in your list with an error so you can retry.
Services that run alongside your application rather than on their own, currently Laravel Nightwatch and Inertia SSR, showed a log viewer stuck on a waiting message and never displayed anything. Their logs now load, in the panel and through the API, with per-instance output for applications running more than one instance.
Settings you left empty when creating a service were saved as empty values instead of falling back to the service's default, so services could start up with settings you never touched blanked out.