← Cloudflare Durable Objects / durable-objects / platform
Цены
За Durable Objects может взиматься плата двух типов: за вычисления и за хранилище.
На плане Workers Free:
- Если вы превысите любой из лимитов бесплатного тарифа, дальнейшие операции этого типа будут завершаться ошибкой.
- Суточные лимиты бесплатного тарифа обновляются в 00:00 UTC.
Тарификация вычислений
Durable Objects тарифицируются по времени вычислений (wall-clock time), пока Durable Object активно выполняется или простаивает в памяти, но не может гибернация. Durable Objects, которые простаивают и допускают гибернацию, не тарифицируются по длительности, даже до того, как среда выполнения перевела их в спящий режим. Запросы к Durable Object поддерживают его активность или создают объект, если он был неактивен.
Для каждого измеряемого параметра оплачиваемым использованием считается объём, превышающий включённую месячную квоту. Перед применением соответствующего тарифа это использование округляется в большую сторону до ближайшей тарифицируемой единицы. Например, 500,000 ГБ-с оплачиваемой длительности вычислений округляются до 1,000,000 ГБ-с и тарифицируются соответственно.
| План Free | Платный план | |
|---|---|---|
| Запросы | 100,000 / день | 1 млн / месяц, + $0.15/млн Включает HTTP-запросы, сеансы RPC1, сообщения WebSocket2, и вызовы alarm |
| Длительность3 | 13,000 GB-s / день | 400,000 GB-s / месяц, + $12.50/млн GB-s4,5 |
Сноски
1 Каждый Сеанс RPC учитывается как один запрос к вашему Durable Object. Каждый Вызов метода RPC на Durable Objects stub представляет собой отдельную RPC сессию и поэтому один тарифицируемый запрос.
Вызовы методов RPC могут возвращать объекты (заглушки), расширяющие RpcTarget и вызывать методы на этих заглушках. Последующие вызовы на возвращённой заглушке относятся к той же RPC-сессии и не тарифицируются как отдельные запросы. Например:
let durableObjectStub = OBJECT_NAMESPACE.get(id); // retrieve Durable Object stub
using foo = await durableObjectStub.bar(); // billed as a request
await foo.baz(); // treated as part of the same RPC session created by calling bar(), not billed as a request
await durableObjectStub.cat(); // billed as a request2 Для создания WebSocket соединения требуется запрос. Исходящие сообщения WebSocket не тарифицируются, как и входящие Пинги протокола WebSocket ↗. Для тарификации только вычислительных запросов к входящим сообщениям WebSocket применяется соотношение 20:1, учитывающее меньший размер сообщений при коммуникации в реальном времени. Например, 100 входящих сообщений WebSocket будут тарифицированы как 5 запросов. Соотношение 20:1 не влияет на метрики и аналитику Durable Object, которые отражают фактическое использование.
3 Автоматические ответные сообщения на уровне приложения, которые обрабатываются state.setWebSocketAutoResponse() не потребуют дополнительного астрономического времени, и поэтому за них не будет взиматься плата.
4 Длительность тарифицируется по астрономическому времени, пока объект активен и не подлежит гибернации, при этом время делится между всеми запросами, одновременно активными для объекта. Вызов accept() для WebSocket в Object приведёт к начислению платы за длительность на всё время, пока WebSocket подключён. Рекомендуется использовать WebSocket Hibernation API, чтобы не платить за длительность после завершения работы всех обработчиков событий. Подробное объяснение см. в Когда с Durable Object начинает взиматься плата за длительность работы?.
5 Тарификация по длительности выполнения учитывает 128 МБ памяти, выделенные вашему Durable Object, независимо от фактического использования. Если ваш аккаунт создаёт много экземпляров одного класса Durable Object, они могут выполняться в одном изоляте на одной физической машине и совместно использовать эти 128 МБ памяти. При этом каждый такой Durable Object всё равно тарифицируется так, как будто ему выделены полные 128 МБ памяти.
Тарификация хранилища
Durable Objects Storage API доступен только изнутри Durable Objects. Стоимость зависит от бэкенда хранилища ваших Durable Objects.
- Durable Objects на основе SQLite (рекомендуется): Хранилище на основе SQLite рекомендуется для всех новых классов Durable Object. На плане Workers Free можно создавать только Durable Objects на основе SQLite и обращаться только к ним.
- Durable Objects с хранилищем ключ-значение: Бэкенд хранилища ключ-значение доступен только на платном плане Workers.
Хранилище на основе SQLite
| план Workers Free | план Workers Paid | |
|---|---|---|
| Прочитанные строки 1,2 | 5 миллионов / день | Первые 25 миллиардов в месяц включены + $0.001 / миллион строк |
| Записанные строки 1,2,3,4 | 100,000 / день | Первые 50 миллионов в месяц включены + $1.00 / миллион строк |
| Хранимые данные SQL 5 | 5 GB (всего) | 5 GB-месяц, + $0.20/ GB-месяц |
Сноски
1 Включённые лимиты и тарифы для операций чтения и записи строк совпадают Тарификация D1, бессерверная база данных SQL от Cloudflare.
2 Методы работы с парами «ключ-значение», такие как get(), put(), delete(), или list() хранят и запрашивают данные в скрытой таблице SQLite и тарифицируются как прочитанные и записанные строки.
3 Каждый setAlarm() учитывается как одна записанная строка.
4 Удаления учитываются как записанные строки.
5 Плата за Durable Objects взимается за хранимые данные до тех пор, пока данные удаляются. После удаления данных объект будет автоматически очищен системой.
Бэкенд хранилища ключ-значение
| план Workers Paid | |
|---|---|
| Единицы запросов на чтение1,2 | 1 млн, + $0.20/млн |
| Единицы запросов на запись3 | 1 млн, + $1.00/млн |
| Запросы на удаление4 | 1 млн, + $1.00/млн |
| Сохранённые данные5 | 1 ГБ, + $0.20/ ГБ-месяц |
Сноски
1 Единица запроса определяется как 4 КБ прочитанных или записанных данных. Если запрос читает или записывает больше 4 КБ, он расходует несколько единиц. Например, запись объёмом 9 КБ израсходует 3 единицы запроса на запись.
2 Операции списка тарифицируются в единицах запросов на чтение, в зависимости от объёма просмотренных данных. Например, запрос списка, который вернёт в сумме 80 КБ ключей и значений, будет тарифицирован как 20 единиц запросов на чтение. Запрос списка, который ничего не вернёт, тарифицируется как 1 единица запроса на чтение.
3 Каждый setAlarm учитывается как одна единица запроса на запись.
4 Запросы на удаление не тарифицируются по объёму. Например, удаление значения размером 100 КБ будет засчитано как один запрос на удаление.
5 Плата за Durable Objects взимается за хранимые данные до тех пор, пока данные не будут удалены. После удаления данных объект автоматически очищается системой.
Запросы, которые попадают в Кэш Durable Objects в памяти или которые используют многоключевые версии get()/put()/delete() методы тарифицируются так же, как если бы это был обычный отдельный запрос для каждого ключа.
Примеры тарификации Compute
В этих примерах не учитывается стоимость Workers, вызывающих Durable Objects. При расчёте стоимости Durable Object учитывайте следующее:
- Неактивные объекты, не получающие запросов, не тарифицируются по длительности.
- WebSocket Hibernation API может значительно снизить расходы, связанные с длительностью, для Durable Objects, обменивающихся данными с клиентами по протоколу WebSocket, особенно если сообщения передаются лишь изредка, с большими интервалами.
- Активное исходящее соединение (через
connect()или исходящий WebSocket) удерживает Durable Object в памяти и приводит к начислению платы за время выполнения до 15 минут на соединение, даже при отсутствии входящих запросов. См. Жизненный цикл Durable Object, где это описано подробнее.
- Активное исходящее соединение (через
Пример 1
Этот пример показывает простой Durable Object, который используется как служба координации и вызывается через HTTP.
- Один Durable Object был вызван Worker 1.5 миллиона раз
- Он активен в течение 1,000,000 секунд в месяце
В этом сценарии предполагаемая ежемесячная стоимость будет рассчитываться следующим образом:
Запросы:
- 1.5 миллиона запросов - включённый 1 миллион запросов = 500,000 тарифицируемых запросов.
- (округлено) 1,000,000 запросов x $0.15 / 1,000,000 = $0.15.
Compute Duration:
- 1,000,000 секунд * 128 МБ / 1 ГБ = 128,000 ГБ-с.
- 128,000 ГБ-с не выходит за пределы включённой квоты в 400,000 ГБ-с = $0.00.
Примерный итог: $0.15 (запросы) + $0.00 (длительность вычислений) + минимум $5/mo использования = $5.15 в месяц
Пример 2
Этот пример показывает приложение на основе Durable Objects со средней нагрузкой, которое использует WebSocket для рассылки состояния игры, чата или пользователя в реальном времени всем подключённым клиентам:
- У каждого из 100 Durable Objects установлено по 50 WebSocket-соединений.
- Клиенты отправляют примерно одно сообщение в минуту в течение восьми активных часов в день, каждый день месяца.
В этом сценарии предполагаемая ежемесячная стоимость будет рассчитываться следующим образом:
Запросы:
- 50 подключений WebSocket * 100 Durable Objects для установки WebSocket-соединений = 5,000 подключений в день * 30 дней = 150,000 запросов на подключение WebSocket.
- 50 сообщений в минуту * 100 Durable Objects * 60 минут * 8 часов * 30 дней = 72,000,000 запросов на отправку сообщений WebSocket.
- 150,000 + (72 миллиона запросов / 20 для коэффициента тарификации сообщений WebSocket) = 3.75 миллиона тарифицируемых запросов.
- 3.75 миллиона запросов - включённый 1 миллион запросов = 2,750,000 оплачиваемых запросов.
- (округлено) 3,000,000 запросов x $0.15 / 1,000,000 = $0.45.
Compute Duration:
- 100 Durable Objects * 60 секунд * 60 минут * 8 часов * 30 дней = 86,400,000 секунд.
- 86,400,000 секунд * 128 MB / 1 GB = 11,059,200 GB-s.
- 11,059,200 ГБ-с - включённые 400,000 ГБ-с = 10,659,200 ГБ-с
- (округлено) 11,000,000 GB-s x $12.50 / 1,000,000 = $137.50.
Примерный итог: $0.45 (запросы) + $137.50 (длительность вычислений) + минимум $5/mo использования = $142.95 в месяц.
Пример 3
Этот пример показывает горизонтально масштабируемое приложение на основе Durable Objects, которое использует WebSocket для передачи состояния конкретного пользователя единственному клиенту, подключённому к каждому Durable Object.
- У каждого из 100 Durable Objects установлено по одному WebSocket-соединению.
- Клиенты отправляли одно сообщение каждую секунду месяца, поэтому Durable Objects были активны весь месяц.
В этом сценарии предполагаемая ежемесячная стоимость будет рассчитываться следующим образом:
Запросы:
- 100 запросов на WebSocket-соединение.
- 1 сообщение в секунду * 100 соединений * 60 секунд * 60 минут * 24 часа * 30 дней = 259,200,000 запросов на сообщения WebSocket.
- 100 + (259.2 миллиона запросов / 20 для коэффициента тарификации WebSocket) = 12,960,100 запросов.
- 12,960,100 запросов - включённый 1 миллион запросов = 11,960,100 тарифицируемых запросов.
- (округлено) 12,000,000 запросов x $0.15 / 1,000,000 = $1.80.
Compute Duration:
- 100 Durable Objects * 60 секунд * 60 минут * 24 часа * 30 дней = 259,200,000 секунд
- 259,200,000 секунд * 128 MB / 1 GB = 33,177,600 GB-s
- 33,177,600 GB-s - включённые 400,000 GB-s = 32,777,600 GB-s
- (округлено) 33,000,000 GB-s x $12.50 / 1,000,000 = $412.50
Примерный итог: $1.80 (запросы) + $412.50 (длительность вычислений) + минимум $5/mo использования = $419.30 в месяц
Пример 4
Этот пример показывает приложение на основе Durable Objects со средней нагрузкой, которое использует WebSocket Hibernation для рассылки состояния игры, чата или пользователя в реальном времени всем подключённым клиентам:
- У каждого из 100 Durable Objects установлено по 100 соединений Hibernatable WebSocket.
- Клиенты отправляют одно сообщение в минуту, и обработка одного сообщения занимает 10 мс в
webSocketMessage()-обработчик. Поскольку каждый Durable Object обслуживает 100 WebSocket-соединений, суммарно каждый Durable Object будет активно выполнять JS 1 секунду в минуту (100 WebSocket * 10 мс).
В этом сценарии предполагаемая ежемесячная стоимость будет рассчитываться следующим образом:
Запросы:
- 100 WebSocket-соединений * 100 Durable Objects для установки WebSocket-соединений = 10,000 начальных запросов на WebSocket-соединение.
- 100 сообщений в минуту1 * 100 Durable Objects * 60 минут * 24 часа * 30 дней = 432,000,000 запросов.
- 10,000 + (432 миллиона запросов / 20 для коэффициента тарификации WebSocket) = 21,610,000 миллионов запросов.
- 21,610,000 запросов - включённый 1 миллион запросов = 20,610,000 оплачиваемых запросов.
- (округлено) 21,000,000 запросов x $0.15 / 1,000,000 = $3.15.
Compute Duration:
- 100 Durable Objects * 1 секунда2 * 60 минут * 24 часа * 30 дней = 4,320,000 секунд
- 4,320,000 секунд * 128 MB / 1 GB = 552,960 GB-s
- 552,960 GB-s - включённые 400,000 GB-s = 152,960 GB-s
- (округлено) 1,000,000 GB-s x $12.50 / 1,000,000 = $12.50
Примерный итог: $3.15 (запросы) + $12.50 (длительность вычислений) + минимум $5/mo использования = $20.65 в месяц
1 100 сообщений в минуту получается из того, что к каждому DO подключаются 100 клиентов, и каждый отправляет 1 сообщение в минуту.
2 В примере используется 1 секунда, потому что каждый Durable Object активен 1 секунду в минуту. Это также можно представить как 432 миллиона запросов, каждый из которых выполняется 10 мс (4,320,000 секунд).
Часто задаваемые вопросы
Когда с Durable Object начинает взиматься плата за длительность работы?
С Durable Object взимается плата за длительность, когда он активно выполняет JavaScript, обрабатывая запрос или запуская обработчики событий, либо когда он простаивает, но не соответствует условия для перехода в спящий режим. Неактивный Durable Object, соответствующий условиям гибернации, не влечёт начисления платы за длительность выполнения, даже в течение короткого промежутка времени перед тем, как runtime переводит его в гибернацию.
После того как объект вытеснен из памяти, при следующем обращении к нему он будет пересоздан (конструктор будет вызван заново).
Есть несколько факторов, которые могут помешать Durable Object перейти в спящий режим, из-за чего с вас продолжат взимать плату за время выполнения.
Дополнительную информацию можно найти в Жизненный цикл Durable Object.
Учитывается ли пустая таблица или база данных SQLite в объёме моего хранилища?
Да, хотя и минимально. Пустые таблицы могут занимать от нескольких килобайт в зависимости от количества столбцов (ширины таблицы). Пустая база данных SQLite занимает приблизительно 12 КБ.
Учитываются ли метаданные, хранящиеся в Durable Objects, в объёме моего хранилища?
Каждая запись в Durable Object на основе SQLite сохраняет небольшой объём метаданных во внутренних таблицах Durable Object, которые учитываются в оплачиваемом объёме хранилища.
Метаданные остаются в Durable Object, пока вы не вызовете deleteAll().