mirror of
https://github.com/danbulant/design
synced 2026-05-19 04:08:46 +00:00
Add data retention
This commit is contained in:
parent
b91b549086
commit
90da170289
2 changed files with 38 additions and 16 deletions
|
|
@ -12,27 +12,27 @@
|
|||
const data = [
|
||||
{
|
||||
name: "Cloudflare R2",
|
||||
price: ({ storage, egress, fileCount }) => 10 * storage + Math.max(0, fileCount-10e6)*0.36/1e6,
|
||||
price: ({ storage, egress, fileCount, dataRetention }) => 10 * storage + Math.max(0, fileCount-10e6)*0.36/1e6,
|
||||
color: "orange",
|
||||
link: "cloudflare-r2"
|
||||
}, {
|
||||
name: "Wasabi",
|
||||
price: ({ storage, egress, fileCount}) => 5 * storage,
|
||||
price: ({ storage, egress, fileCount, dataRetention }) => 5 * storage * (90/dataRetention),
|
||||
color: "green",
|
||||
link: "wasabi"
|
||||
}, {
|
||||
name: "Backblaze B2",
|
||||
price: ({ storage, egress, fileCount}) => 4 * storage + 10 * egress + Math.max(0, fileCount - 2500)*4/10e6,
|
||||
price: ({ storage, egress, fileCount, dataRetention }) => 4 * storage + 10 * egress + Math.max(0, fileCount - 2500)*4/10e6,
|
||||
color: "red",
|
||||
link: "backblaze-b2"
|
||||
}, {
|
||||
name: "DO Spaces",
|
||||
price: ({ storage, egress, fileCount}) => 20 * storage + 10 * egress,
|
||||
price: ({ storage, egress, fileCount, dataRetention }) => 20 * storage + 10 * egress,
|
||||
color: "blue",
|
||||
link: "digitalocean-spaces"
|
||||
}, {
|
||||
name: "Storj.io",
|
||||
price: ({ storage, egress, fileCount}) => 4 * storage + 7 * egress,
|
||||
price: ({ storage, egress, fileCount, dataRetention }) => 4 * storage + 7 * egress,
|
||||
color: "rgb(0,120,180)",
|
||||
link: "storjio"
|
||||
}
|
||||
|
|
@ -52,9 +52,9 @@
|
|||
}
|
||||
const m = spring();
|
||||
$: size = w < 480 ? 'small' : w < 640 ? 'medium' : 'large';
|
||||
$: $m = data.map((d, i) => ({ x: i, y: d.price({ storage, egress, fileCount }) }));
|
||||
$: $m = data.map((d, i) => ({ x: i, y: d.price({ storage, egress, fileCount, dataRetention }) }));
|
||||
let max = spring();
|
||||
$: $max = Math.max(50, ...data.map(d => d.price({ storage, egress, fileCount }) + d.price({ storage, egress, fileCount }) * 0.2));
|
||||
$: $max = Math.max(50, ...data.map(d => d.price({ storage, egress, fileCount, dataRetention }) + d.price({ storage, egress, fileCount, dataRetention }) * 0.2));
|
||||
onMount(() => {
|
||||
w = el.clientWidth;
|
||||
});
|
||||
|
|
@ -63,6 +63,8 @@
|
|||
$: if(storage < 1) storage = 1;
|
||||
let egress = 1;
|
||||
$: if(egress < 1) egress = 1;
|
||||
let dataRetention = 90;
|
||||
$: if(dataRetention < 1) dataRetention = 1;
|
||||
</script>
|
||||
|
||||
<label for="storage">Storage used</label>
|
||||
|
|
@ -77,7 +79,7 @@
|
|||
<div class="flex">
|
||||
<input type="range" min="1" max="1000" step="1" bind:value={egress}>
|
||||
<div class="input-tb">
|
||||
<input name="storage" id="egress" type="number" min="1" max="1000" step="1" bind:value={egress}>
|
||||
<input name="egress" id="egress" type="number" min="1" max="1000" step="1" bind:value={egress}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -107,18 +109,27 @@
|
|||
|
||||
<p class="credit">
|
||||
Source: Respective pricing pages (see links above), on <Date value="2022-05-16T16:00" /> <small>(hover for quick relative time)</small> <br />
|
||||
Prices are estimates, expecting that traffic is uniform during the month, and that the average size of a file is {averageSize}MB ({fileCount} files downloaded). Doesn't account for listings or deletions. Uploads are not using multipart.
|
||||
Prices are estimates, expecting that traffic is uniform during the month, and that the average size of a file is {averageSize}MB ({Math.ceil(fileCount)} files downloaded). Doesn't account for listings or deletions. Uploads are not using multipart.
|
||||
</p>
|
||||
|
||||
<details>
|
||||
<summary> Additional options and details </summary>
|
||||
|
||||
<label for="egress">Average file size</label>
|
||||
<label for="file-size">Average file size</label>
|
||||
<small>It does account file count into the pricing maths, defaults to 1 file downloaded = GetObject op. I think that the ops pricing is just anti-spam measure.</small>
|
||||
<div class="flex">
|
||||
<input type="range" min="1" max="1000" step="1" bind:value={averageSize}>
|
||||
<div class="input-text input-mb">
|
||||
<input name="storage" id="egress" type="number" min="1" max="1000" step="1" bind:value={averageSize}>
|
||||
<input name="file-size" id="file-size" type="number" min="1" max="1000" step="1" bind:value={averageSize}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label for="days">Average data retention</label>
|
||||
<small>Only affects Wasabi pricing.</small>
|
||||
<div class="flex">
|
||||
<input type="range" min="1" max="90" step="1" bind:value={dataRetention}>
|
||||
<div class="input-text input-days">
|
||||
<input name="days" id="days" type="number" min="1" max="90" step="1" bind:value={dataRetention}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -133,7 +144,7 @@
|
|||
<tr>
|
||||
<td><a href="#{service.link}">{service.name}</a></td>
|
||||
<td><code>{service.price.toString().substring(service.price.toString().indexOf("=>") + 3)}</code></td>
|
||||
<td>{Math.floor(service.price({ egress, fileCount, storage }))}</td>
|
||||
<td>${Math.floor(service.price({ egress, fileCount, storage, dataRetention }))}/TB/month</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
|
|
@ -157,7 +168,6 @@
|
|||
position: relative;
|
||||
}
|
||||
.input-text::after {
|
||||
content: "TB";
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: .5em;
|
||||
|
|
@ -173,6 +183,12 @@
|
|||
.input-mb::after {
|
||||
content: "MB";
|
||||
}
|
||||
.input-days::after {
|
||||
content: "days";
|
||||
}
|
||||
input#days {
|
||||
width: 5.5em;
|
||||
}
|
||||
.input-text:hover::after, .input-text:focus-within::after {
|
||||
right: 1.5em;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ Out of the below, I only used `storj.io`. Others are just quick info based on th
|
|||
|
||||
There's also a simplified comparison tool at the bottom.
|
||||
|
||||
`egress` means outbound transfers.
|
||||
`egress` means outbound transfers. Some services have a monthly minimum fee, from what I checked it's 1TB or less. Some services may also have a minimum billable size (Wasabi 4KB, AWS 128KB).
|
||||
|
||||
The services are in no particular order (I tried a bit by popularity, but no exact metrics were used for sorting).
|
||||
|
||||
|
|
@ -48,9 +48,15 @@ Delete operations are free (`DeleteObject`, `DeleteBucket`, `DeleteMultipartUplo
|
|||
|
||||
## Wasabi
|
||||
|
||||
***$5.99/TB/month***
|
||||
EU/NA: ***$5.99/TB/month***
|
||||
APAC: ***$6.99/TB/month***
|
||||
|
||||
No API charge/egress.
|
||||
No API charge/egress. Minimum fee of 1TB storage.
|
||||
|
||||
As mentioned by @spiffytech (via utteranc.es, see the bottom of the page), Wasabi always bills for a minimum of 90 days, even if you delete the files sooner.
|
||||
If that's of a concern, try adjusting the slider in the "additional options" at the bottom graph. When you replace a file during those 90 days, it will still be billed (as if you deleted the file and created a new one).
|
||||
|
||||
Has a policy that egress shouldn't be higher than the stored amount. Consider using CDN or a cache layer.
|
||||
|
||||
[Home page](https://wasabi.com) | [Pricing page](https://wasabi.com/cloud-storage-pricing/)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue