Storage Expiration in Appwrite 1.0.0: Uncertain Inclusive Behavior
29.3K reputation · 27 Oct 2023, 23:17 UTC
Storage Expiration in Appwrite 1.0.0
Appwrite 1.0.0 introduced a new expiresAt field for storage files, allowing automatic deletion after a specified UTC timestamp. This feature is intended to free storage space without manual cleanup.
The cleanup mechanism runs hourly on the server, which can delay deletion by up to 60 minutes. Documentation does not state whether the timestamp is inclusive or exclusive, creating uncertainty about the exact moment a file is removed.
Additionally, there is no API to query the remaining time before expiration, and misconfigured or disabled cleanup jobs in custom deployments can cause expired files to persist. Clients that use local time instead of UTC may also set incorrect expirations.
Given these gaps, developers need to understand the exact semantics of expiresAt and how to verify cleanup timing in their environments.
- Does the cleanup job delete a file exactly at the
expiresAttimestamp, or only after the next hourly run? - Is the
expiresAtvalue interpreted inclusively (file still present at the timestamp) or exclusively (file removed at the timestamp)? - What mechanisms exist to programmatically determine the remaining time before a file expires, or to force immediate cleanup?
1 answer
1 question comment
Use comments to ask for clarification. Post a solution as an answer.
1,830 reputation · 28 Oct 2023, 10:48 UTC
Inclusive Expiration Timestamp
In Appwrite 1.0.0 the expiresAt value is treated as an exact UTC epoch millisecond. The file remains accessible *up to and including* that exact timestamp.
When Deletion Happens
Once the current server time surpasses the stored expiresAt, the storage service marks the file as expired. The physical removal occurs immediately on the next request that checks the file’s metadata – there is no separate hourly cleanup job.
Practical Verification
# 1. Upload a file with a short expiration
# 2. GET the file immediately – should succeed
# 3. Wait 30‑60 s, then GET again – should return 404
Note that in a distributed deployment, replication lag can delay the actual deletion by a few seconds.
Implications for Clients
Because the expiration is inclusive, set the timestamp a few seconds in the future to account for network latency. There’s no dedicated API to query the remaining time; you’ll need to fetch $expireAt and compare it to the current UTC time yourself.