A connection test in a backup console checks that a hostname resolves, that a TLS session negotiates, that an access key is accepted, and that a bucket answers a list request. It passes in seconds, and it proves almost nothing about whether nightly jobs will still complete six months from now. The operations backup software depends on sit further down the API surface, and they fail in ways a green check mark was never designed to catch.
S3 compatibility is not a single property a target either has or does not have. It is a long list of behaviors, and a product can implement most of them while implementing one differently from what a backup vendor assumed. A target can serve puts and gets flawlessly and still strand terabytes of unfinished uploads, refuse a retention setting the job treats as mandatory, or turn an overload into a failed backup.
The question worth asking before a purchase order is therefore not whether a target is S3 compatible, but which operations in the backup product's write, retention and restore paths have been exercised against it, at a volume and under failure conditions resembling production. That is a test plan rather than a claim, and it fits in an afternoon.
What the connection test leaves untested
The built in test in most backup products issues a handful of small requests. It confirms the endpoint answers on the expected port, the certificate chain validates, credentials work, and the bucket exists. Every one of those requests is sequential, and made while nothing else is running.
Production looks nothing like that. A job opens many parallel streams, writes objects in chunks measured in megabytes, holds uploads open for minutes, applies retention at write time, and lists prefixes holding hundreds of thousands of keys, while a copy job and a health check compete for the same endpoint.
Multipart upload, abort and the cleanup nobody watches
Backup software writes large objects in parts. It initiates a multipart upload, sends numbered parts in parallel, and completes it with a manifest. If the job is canceled or the backup server reboots partway through, those parts stay on the target as an upload that was never completed and never aborted. They consume capacity and are invisible to an ordinary object listing.
The test is direct. Start a large write, kill it in flight, then ask the target to list in progress multipart uploads. Abort the upload and confirm consumed capacity actually falls, not merely the object count. Then check whether a lifecycle rule for incomplete uploads can be configured and whether it runs, since that rule is what stands between an intermittent network and a slowly filling repository.
Two details deserve a further hour. Products differ in the part size and count they choose, so a target with unusual limits fails on the largest objects rather than the first. And parts get retried, so the same part number arrives twice and the target must accept the second copy without corrupting the manifest. A quiet failure there produces an object that completes successfully and reads back wrong, discovered only at restore.
Versioning, delete markers and object lock semantics
Immutability is where compatibility claims are most often thinner than they sound. Object lock depends on versioning, and versioning changes what a delete does. Instead of removing data, a delete places a marker over the current version and earlier versions remain. Software that expires restore points relies on this behaving exactly as specified, since its capacity accounting assumes old versions eventually go away.
The test is a short sequence. Write an object, overwrite it, delete it, then list versions and confirm the versions and the marker all appear. Apply retention with a near future date, attempt to delete that version, and confirm the target refuses rather than silently succeeding. Attempt to shorten the date, confirm refusal, then extend it and confirm acceptance. Apply a legal hold and confirm only an identity holding the right permission can lift it. The distinction between governance and compliance retention modes is exactly the distinction between a hold an administrator can lift and one nobody can, and a target that treats both alike is not offering what object lock is supposed to guarantee.
| Operation | Why the backup product depends on it | What the test should prove |
|---|---|---|
| Abort of an incomplete upload | Interrupted jobs leave parts that consume capacity invisibly | Parts list, abort frees space, cleanup rules run |
| Retention applied at write time | Restore points must be immutable from the moment they land | Delete refused, shortening refused, extension accepted |
| Versioning and delete markers | Expiry accounting assumes standard version behavior | Versions and markers list correctly, old versions expire |
| Paged listing of large prefixes | Reconciliation walks every key the repository holds | Paging works and listing time stays predictable |
| Retryable error codes under load | The client backs off instead of failing the whole job | Overload returns a retryable status, not a reset connection |
| Read back of a large object | A restore reads back what was written, boundaries included | Checksums match on objects written in parts |
Listing, conditional requests and behavior under load
Listing is the operation most often underestimated. A mature repository holds a very large number of keys, and several routine tasks walk the whole set: retention processing, health checks, capacity reporting, reconciliation after an interruption. Listing returns in pages, and a full walk grows with the key count. A target that lists a nearly empty bucket instantly can take minutes per pass once it is full, turning a nightly task into one still running when the next backup starts. That test needs a synthetic population of keys, not the fifty objects a short trial produces.
Conditional requests are the quieter case. Backup products use headers that make a request succeed only if an object matches a given state, and rely on a specific failure status when it does not. A target answering with a generic error instead can send the client down a retry path that never resolves.
Error semantics under load decide whether a busy night becomes a failed night. When a target is saturated, correct behavior is a retryable response telling the client to slow down. One that instead resets the connection, or returns a code the client treats as permanent, converts a temporary condition into a job failure. Producing that state deliberately, with several jobs at once against an undersized configuration, is the most informative hour in the plan, and the point at which jobs stopped recovering feeds into how the repository is sized.
Where ARTESCA fits
ARTESCA is object storage software used as a backup target, presenting an S3 compatible API and supporting S3 Object Lock for immutable backup storage. It is built to serve backup software, including Veeam, so the operations described above are the ones it exists to handle.
Because it runs on infrastructure the customer owns, the test plan can be executed on the actual hardware, network path and certificate configuration that will carry production traffic. A test against a demonstration instance elsewhere answers a different question than a test against the nodes and switch ports that will hold the data.
Capacity in the range it serves, roughly 50 TB to 8.5 PB, is also the range where listing behavior and multipart cleanup stop being theoretical rather than a feature checklist entry.
Running the plan before committing
The plan belongs in a short document with a pass or fail column, kept with the repository documentation rather than in one person's notes. Each line names an operation, how it was exercised, the result and the date. Run it again when either the storage or the backup software is updated, and before moving older restore points onto a new target.
An afternoon covers the core: an interrupted large write and its cleanup, a retention and legal hold sequence, a listing pass against a populated bucket, a deliberate overload, and a restore of something written before it. Keep the exact error text the product produced, since a support conversation six months later will turn on that wording.
If time runs short, the test to insist on is the restore. Every other check confirms data was accepted. Only a restore confirms it comes back, and only a restore of an object large enough to have been written in parts confirms the part boundaries were handled correctly.
