Las solicitudes que realices a las tiendas de datos pueden fallar debido a una mala conectividad u otros problemas. Para manejar errores y devolver mensajes con un código de error, envuelve las funciones de la tienda de datos en pcall().
Una llamada de escritura fallida, como UpdateAsync(), significa que el servidor del juego no recibió una respuesta exitosa. No siempre garantiza que la escritura de backend no haya ocurrido. En algunos escenarios de fallo, el estado final de la escritura puede ser desconocido para el llamador hasta que se verifique con una lectura posterior sin caché.
Referencia de códigos de error
| Código de error | Nombre del error | Mensaje de error | Notas | |
|---|---|---|---|---|
| 101 | KeyNameEmpty | El nombre de la clave no puede estar vacío. | Verifica si la clave ingresada en la función de la tienda de datos es una cadena vacía. | |
| 102 | KeyNameLimit | El nombre de la clave excede el límite de 50 caracteres. | Verifica si la clave ingresada en la función de la tienda de datos excede una longitud de 50. | |
| 103 | ValueNotAllowed | No se puede permitir X en DataStore. | Una función de actualización errónea devolvió un valor de tipo X. | |
| 104 | CantStoreValue | No se puede almacenar X en DataStore. | La función de actualización devolvió un valor de tipo X que no se serializó. | |
| 105 | ValueTooLarge | El valor serializado excede el límite de X. | Si estás configurando un valor con SetAsync() o UpdateAsync(), la longitud serializada del valor no puede exceder el tamaño X. Para comprobar la longitud serializada de los datos, utiliza JSONEncode(). | |
| 106 | MaxValueInvalid | MaxValue debe ser un número entero. | Si estás pasando un valor máximo a GetSortedAsync() para un OrderedDataStore, debe ser un número entero. | |
| 106 | MinValueInvalid | MinValue debe ser un número entero. | Si estás pasando un valor mínimo a GetSortedAsync() para un OrderedDataStore, debe ser un número entero. | |
| 106 | PageSizeGreater | PageSize debe estar dentro de un rango predefinido. | El tamaño de página mínimo para un OrderedDataStore es 1. | |
| 106 | PageSizeLesser | PageSize debe estar dentro de un rango predefinido. | El tamaño máximo de página para un OrderedDataStore es 100. | |
| 107 | MinMaxOrderInvalid | MaxValue debe ser mayor o igual a MinValue. | El valor máximo debe ser mayor o igual al valor mínimo para GetSortedAsync(). | |
| 301 | GetAsyncThrottle | Solicitud GetAsync descartada. La solicitud fue limitada pero la cola estaba llena. | La solicitud GetAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes en la tasa de transferencia actual. | |
| 302 | SetAsyncThrottle | Solicitud SetAsync descartada. La solicitud fue limitada pero la cola estaba llena. | La solicitud SetAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes en la tasa de transferencia actual. | |
| 303 | IncreAsyncThrottle | Solicitud IncrementAsync descartada. La solicitud fue limitada pero la cola estaba llena. | La solicitud IncrementAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes en la tasa de transferencia actual. | |
| 304 | UpdateAsyncThrottle | Solicitud UpdateAsync descartada. La solicitud fue limitada pero la cola estaba llena. | La solicitud UpdateAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes en la tasa de transferencia actual. | |
| 304 | TransformThrottle | Solicitud UpdateAsync descartada. La solicitud fue limitada pero la cola estaba llena. | La solicitud UpdateAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes en la tasa de transferencia actual. | |
| 305 | GetSortedThrottle | Solicitud GetSorted descartada. La solicitud fue limitada pero la cola estaba llena. | La solicitud GetSortedAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes en la tasa de transferencia actual. | |
| 306 | RemoveAsyncThrottle | Solicitud RemoveAsync descartada. La solicitud fue limitada pero la cola estaba llena. | La solicitud RemoveAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes en la tasa de transferencia actual. | |
| 401 | DataModelNoAccess | La solicitud falló. DataModel es inaccesible mientras la experiencia se está apagando. | DataModel no está inicializado porque la experiencia se está apagando. | |
| 402 | LuaWebSrvsNoAccess | La solicitud falló. LuaWebService es inaccesible mientras la experiencia se está apagando. | LuaWebService no está inicializado porque la experiencia se está apagando. | |
| 403 | StudioAccessToApisNotAllowed | No se puede escribir en DataStore desde Studio porque el acceso a la API no está habilitado. | El acceso a la API debe estar activo para usar tiendas de datos en Studio. | |
| 404 | InternalError | OrderedDataStore no existe. | El OrderedDataStore asociado con esta solicitud no fue encontrado. Esto podría ser una señal de corrupción de datos. Intenta nuevamente más tarde. | |
| 501 | InternalError | No se puede analizar la respuesta porque los datos pueden estar corruptos. | El servidor no pudo analizar la respuesta a tu solicitud. Esto podría ser una señal de corrupción de datos. Intenta nuevamente más tarde. | |
| 502 | RequestRejected | Los servicios de API rechazaron la solicitud con el error X. | El error X ocurrió al procesar en los servidores de Roblox. Intenta nuevamente más tarde. | |
| 503 | InternalError | La solicitud de la tienda de datos fue exitosa, pero la clave no fue encontrada. | La clave solicitada no fue encontrada en la tienda de datos. Esto podría ser una señal de corrupción de datos. Intenta nuevamente más tarde. | |
| 504 | InternalError | La solicitud de la tienda de datos fue exitosa pero la respuesta no fue formateada correctamente. | El servidor no pudo analizar la respuesta a tu solicitud. Esto podría ser una señal de corrupción de datos. Intenta nuevamente más tarde. | |
| 505 | InternalError | La solicitud de OrderedDataStore fue exitosa, pero la respuesta no fue formateada correctamente. | El servidor no pudo analizar la respuesta a tu solicitud de OrderedDataStore. Esto podría ser una señal de corrupción de datos. Intenta nuevamente más tarde. | |
| 509 | OperationNotAllowed | Las operaciones de la tienda de datos están bloqueadas mientras se ejecuta en un RCC Personal para prevenir posibles corrupciones de datos. | Las escrituras en la tienda de datos están bloqueadas en canales RCC privados. | |
| 511 | AttributeSizeTooLarge | El tamaño del atributo de metadatos excede el límite de X. | El tamaño de los metadatos serializados excede el límite de X. El valor X es dinámico. Si el tamaño cambia, el valor también cambia. | |
| 512 | UserIdLimitExceeded | El tamaño del UserID excede el límite de X. | La longitud del array de IDs de usuario proporcionado por el usuario excede el límite de X. | |
| 513 | AttributeFormatError | El formato del atributo userId es inválido. | El ID de usuario proporcionado no es un número. | |
| 513 | AttributeFormatError | El formato de los metadatos del atributo es inválido. | Los metadatos no son una tabla. | |
| GetVersionAsyncThrottle | Solicitud GetVersionAsync descartada. La solicitud fue limitada. | La solicitud GetVersionAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes en la tasa de transferencia actual. | ||
| GetVersionAtTimeAsyncThrottle | Solicitud GetVersionAtTimeAsync descartada. La solicitud fue limitada. | La solicitud GetVersionAtTimeAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes en la tasa de transferencia actual. | ||
| ListDataStoresAsyncThrottle | Solicitud ListDataStoresAsync descartada. La solicitud fue limitada. | La solicitud ListDataStoresAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes en la tasa de transferencia actual. | ||
| ListKeysAsyncThrottle | Solicitud ListKeysAsync descartada. La solicitud fue limitada. | La solicitud ListKeysAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes en la tasa de transferencia actual. | ||
| ListVersionsAsyncThrottle | Solicitud ListVersionsAsync descartada. La solicitud fue limitada. | La solicitud ListVersionsAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes en la tasa de transferencia actual. | ||
| RemoveVersionAsyncThrottle | Solicitud RemoveVersionAsync descartada. La solicitud fue limitada. | La solicitud RemoveVersionAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes en la tasa de transferencia actual. | ||
| InvalidTimestamp | La marca de tiempo debe ser positiva y no más de diez minutos en el futuro. | La marca de tiempo proporcionada a GetVersionAtTimeAsync() no era válida. | ||
| StandardReadExperienceThrottled | La solicitud StandardRead fue limitada por límites de experiencia. | Una solicitud a GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), o la lectura de UpdateAsync() en una tienda de datos estándar excedió el límite de tasa de experiencia StandardRead. | ||
| StandardWriteExperienceThrottled | La solicitud StandardWrite fue limitada por límites de experiencia. | Una solicitud a SetAsync(), IncrementAsync(), o la escritura de UpdateAsync() en una tienda de datos estándar excedió el límite de tasa de experiencia StandardWrite. | ||
| StandardListExperienceThrottled | La solicitud StandardList fue limitada por límites de experiencia. | Una solicitud a ListKeysAsync(), ListVersionsAsync(), o ListDataStoresAsync() en tiendas de datos estándar excedió el límite de tasa de experiencia StandardList. | ||
| StandardRemoveExperienceThrottled | La solicitud StandardRemove fue limitada por límites de experiencia. | Una solicitud a RemoveAsync() en una tienda de datos estándar excedió el límite de tasa de experiencia StandardRemove. | ||
| OrderedReadExperienceThrottled | La solicitud OrderedRead fue limitada por límites de experiencia. | Una solicitud a GetAsync() o la lectura de UpdateAsync() en una tienda de datos ordenada excedió el límite de tasa de experiencia OrderedRead. | ||
| OrderedWriteExperienceThrottled | La solicitud OrderedWrite fue limitada por límites de experiencia. | Una solicitud a SetAsync(), IncrementAsync(), o la escritura de UpdateAsync() en una tienda de datos ordenada excedió el límite de tasa de experiencia OrderedWrite. | ||
| OrderedListExperienceThrottled | La solicitud OrderedList fue limitada por límites de experiencia. | Una solicitud a GetSortedAsync() en una tienda de datos ordenada excedió el límite de tasa de experiencia OrderedList. | ||
| OrderedRemoveExperienceThrottled | La solicitud OrderedRemove fue limitada por límites de experiencia. | Una solicitud a RemoveAsync() en una tienda de datos ordenada excedió el límite de tasa de experiencia OrderedRemove. | ||
| StandardReadGameServerThrottled | La solicitud StandardRead fue limitada por límites de servidor de juego o la cola de solicitudes estaba llena. | Una solicitud a GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), o la lectura de UpdateAsync() en una tienda de datos estándar excedió el límite de tasa de servidor de juego StandardRead. | ||
| StandardWriteGameServerThrottled | La solicitud StandardWrite fue limitada por límites de servidor de juego o la cola de solicitudes estaba llena. | Una solicitud a SetAsync(), IncrementAsync(), o la escritura de UpdateAsync() en una tienda de datos estándar excedió el límite de tasa de servidor de juego StandardWrite. | ||
| StandardListGameServerThrottled | La solicitud StandardList fue limitada por límites de servidor de juego o la cola de solicitudes estaba llena. | Una solicitud a ListKeysAsync(), ListVersionsAsync(), o ListDataStoresAsync() en tiendas de datos estándar excedió el límite de tasa de servidor de juego StandardList. | ||
| StandardRemoveGameServerThrottled | La solicitud StandardRemove fue limitada por límites de servidor de juego o la cola de solicitudes estaba llena. | Una solicitud a RemoveAsync() en una tienda de datos estándar excedió el límite de tasa de servidor de juego StandardRemove. | ||
| OrderedReadGameServerThrottled | La solicitud OrderedRead fue limitada por límites de servidor de juego o la cola de solicitudes estaba llena. | Una solicitud a GetAsync() o la lectura de UpdateAsync() en una tienda de datos ordenada excedió el límite de tasa de servidor de juego OrderedRead. | ||
| OrderedWriteGameServerThrottled | La solicitud OrderedWrite fue limitada por límites de servidor de juego o la cola de solicitudes estaba llena. | Una solicitud a SetAsync(), IncrementAsync(), o la escritura de UpdateAsync() en una tienda de datos ordenada excedió el límite de tasa de servidor de juego OrderedWrite. | ||
| OrderedListGameServerThrottled | La solicitud OrderedList fue limitada por límites de servidor de juego o la cola de solicitudes estaba llena. | Una solicitud a GetSortedAsync() en una tienda de datos ordenada excedió el límite de tasa de servidor de juego OrderedList. | ||
| OrderedRemoveGameServerThrottled | La solicitud OrderedRemove fue limitada por límites de servidor de juego o la cola de solicitudes estaba llena. | Una solicitud a RemoveAsync() en una tienda de datos ordenada excedió el límite de tasa de servidor de juego OrderedRemove. |
Códigos de error del servidor
| Nombre del error | Mensaje de error | Notas |
|---|---|---|
| DatastoreDeleted | La tienda de datos ha sido eliminada. | No se pudo realizar una operación en la tienda de datos porque la tienda de datos fue eliminada previamente. |
| DatastoreThrottled | La tasa de solicitudes excede el máximo permitido para la datastore. | Se enviaron demasiadas solicitudes a una sola tienda de datos. |
| InternalServerError | Ocurrió un error interno del servidor. | Error ocasional en los servidores de Roblox. Intenta de nuevo, idealmente con una retroceso exponencial. |
| InvalidExclusiveStartKey | La clave de inicio exclusiva proporcionada no es válida. | La clave de inicio exclusiva (cursor) proporcionada a una operación de lista como ListKeysAsync() no es válida. |
| InvalidPlace | El lugar proporcionado es inválido. | No hay un ID de universo coincidente para el lugar. Intenta de nuevo más tarde. |
| InvalidTarget | El objetivo proporcionado es inválido. | El nombre de la clave de la tienda de datos ordenada excede el límite de 50 caracteres. |
| InvalidUniverse | El universo proporcionado es inválido. | No hay un ID de lugar coincidente para el universo. Intenta de nuevo más tarde. |
| InvalidUserIds | Los IDs de usuario proporcionados tienen un formato inválido. | No se pudo analizar los IDs de usuario. |
| KeyThrottled | La tasa de solicitudes excede el máximo permitido para la clave. | La tasa de solicitudes excede la tasa de solicitud máxima permitida para una sola clave. |
| KeyNotFound | La clave solicitada no existe. | La clave no existe. |
| N/A | No hay páginas a las que avanzar. | Este error ocurre cuando llamas a Pages:AdvanceToNextPageAsync() en la última página. |
| StandardReadExperienceThrottled | La tasa de solicitud de lectura estándar excede el máximo permitido para la experiencia. | Una solicitud a GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), o la lectura de UpdateAsync() en una tienda de datos estándar excedió el límite de tasa de experiencia StandardRead. |
| StandardWriteExperienceThrottled | La tasa de solicitud de escritura estándar excede el máximo permitido para la experiencia. | Una solicitud a SetAsync(), IncrementAsync(), o la escritura de UpdateAsync() en una tienda de datos estándar excedió el límite de tasa de experiencia StandardWrite. |
| StandardListExperienceThrottled | La tasa de solicitud de lista estándar excede el máximo permitido para la experiencia. | Una solicitud a ListKeysAsync(), ListVersionsAsync(), o ListDataStoresAsync() en tiendas de datos estándar excedió el límite de tasa de experiencia StandardList. |
| StandardRemoveExperienceThrottled | La tasa de solicitud de eliminación estándar excede el máximo permitido para la experiencia. | Una solicitud a RemoveAsync() en una tienda de datos estándar excedió el límite de tasa de experiencia StandardRemove. |
| OrderedReadExperienceThrottled | La tasa de solicitud de lectura ordenada excede el máximo permitido para la experiencia. | Una solicitud a GetAsync() o la lectura de UpdateAsync() en una tienda de datos ordenada excedió el límite de tasa de experiencia OrderedRead. |
| OrderedWriteExperienceThrottled | La tasa de solicitud de escritura ordenada excede el máximo permitido para la experiencia. | Una solicitud a SetAsync(), IncrementAsync(), o la escritura de UpdateAsync() en una tienda de datos ordenada excedió el límite de tasa de experiencia OrderedWrite. |
| OrderedListExperienceThrottled | La tasa de solicitud de lista ordenada excede el máximo permitido para la experiencia. | Una solicitud a GetSortedAsync() en una tienda de datos ordenada excedió el límite de tasa de experiencia OrderedList. |
| OrderedRemoveExperienceThrottled | La tasa de solicitud de eliminación ordenada excede el máximo permitido para la experiencia. | Una solicitud a RemoveAsync() en una tienda de datos ordenada excedió el límite de tasa de experiencia OrderedRemove. |
Límites
Los modelos de datos tienen límites. Si una experiencia excede estos límites, el servicio limita automáticamente el uso de la tienda de datos de la experiencia y coloca futuras solicitudes en una de las siguientes colas:
- Establecer
- Conjunto ordenado
- Obtener
- Obtener ordenado
Las solicitudes en una cola se manejan en el orden en que se reciben. La función llamada continúa cediendo mientras su solicitud siga en la cola. Si la clave de la tienda de datos en sí está limitada, la solicitud se coloca en una cola, pero se salta temporalmente.
Cada cola tiene un límite de 30 solicitudes. Cuando se alcanza el límite de una cola, las solicitudes fallan con un código de error en el rango 301-306, indicando que las solicitudes han sido completamente descartadas.
Límites de acceso
Las tiendas de datos están sujetas tanto a límites de experiencia como a límites del servidor. Los límites a nivel de experiencia se escalan con el total de usuarios concurrentes en la experiencia, mientras que los límites a nivel de servidor son configurables y están destinados a ser utilizados como una herramienta por el creador.
Límites de experiencia
Cada experiencia tiene permitido un cierto número de solicitudes de tienda de datos basado en el tipo de tienda de datos, el tipo de solicitud y el número de usuarios concurrentes. Para cada tipo de tienda de datos y tipo de solicitud, el límite es compartido entre todas las funciones listadas.
- UpdateAsync() consume tanto del presupuesto de solicitudes de lectura como de escritura. Una sola llamada disminuirá ambos límites.
- El servidor de juego y Open Cloud comparten un presupuesto; el tráfico de Open Cloud puede ser limitado por el uso en la experiencia (y viceversa). Consulta Controlar los límites de tasa para obtener más orientación.
Tiendas de datos estándar
| Tipo de solicitud | API del servidor de juego | API de Open Cloud | Límites compartidos (solicitudes por minuto) |
|---|---|---|---|
| Leer | GetAsync() GetVersionAsync() GetVersionAtTimeAsync() UpdateAsync() | Obtener entrada de la tienda de datos | 300 + usuarios concurrentes × 40 |
| Escribir | SetAsync() IncrementAsync() UpdateAsync() | Crear, actualizar, incrementar entrada de la tienda de datos | 300 + usuarios concurrentes × 20 |
| Listar | ListDataStoresAsync() ListKeysAsync() ListVersionsAsync() | Listar tiendas de datos, listar entradas de la tienda de datos, listar revisiones de entrada de la tienda de datos | 300 + usuarios concurrentes × 2 |
| Eliminar | RemoveAsync() | Eliminar entrada de la tienda de datos, eliminar tienda de datos, restaurar tienda de datos | 300 + usuarios concurrentes × 40 |
Tiendas de datos ordenadas
| Tipo de solicitud | API del servidor de juego | API de Open Cloud | Límites compartidos (solicitudes por minuto) |
|---|---|---|---|
| Leer | GetAsync() UpdateAsync() | Obtener entrada de la tienda de datos ordenada | 300 + usuarios concurrentes × 40 |
| Escribir | SetAsync() IncrementAsync() UpdateAsync() | Crear, actualizar, incrementar entrada de la tienda de datos ordenada | 300 + usuarios concurrentes × 20 |
| Listar | GetSortedAsync() | Listar entradas de la tienda de datos ordenada | 300 + usuarios concurrentes × 2 |
| Eliminar | RemoveAsync() | Eliminar entrada de la tienda de datos ordenada | 300 + usuarios concurrentes × 40 |
Controlar límites de tasa
Dado que las solicitudes de Open Cloud y del servidor de juego son compartidas, es importante controlar independientemente cuánto puede consumir cada una del presupuesto.
Servidor de juego
Los servidores individuales tienen límites incorporados, como se describió anteriormente. Utiliza una combinación de SetRateLimitForRequestType() y GetRequestBudgetForRequestType() para mantener un control detallado sobre la contribución de los servidores individuales al presupuesto total.
Open Cloud
Las solicitudes de Open Cloud requieren una solución de limitación de tasa externa. Te recomendamos uno de los siguientes enfoques:
- (Simple) Agregar un corto tiempo de espera después de cada solicitud, especialmente si llamas a la misma API en un bucle continuo. Establece este tiempo de espera igual a 60 / (consumo de presupuesto deseado por minuto) segundos, como un límite superior. Ten en cuenta que este enfoque no permite que las solicitudes se envíen en ráfagas.
- (Robusto) Implementar un limitador de tasa local utilizando la estrategia de cubo con fuga.
Los siguientes ejemplos de código en Node.js incluyen implementaciones de referencia.
const apiKey = process.env.API_KEY;
if (!apiKey) {
throw new Error('La variable de entorno API_KEY no está configurada.');
}
const apiHeaderKey = 'x-api-key';
const universeId = '';
const dataStoreId = 'Inventario';
const baseUrl = 'https://apis.roblox.com/cloud/v2/';
// --- Configuración de limitación de tasa por operación (solicitudes por minuto) ---
const LIST_RATE_PER_MIN = 60;
const GET_RATE_PER_MIN = 120;
const UPDATE_RATE_PER_MIN = 60;
// Espaciado superior para cada operación: 60 / (solicitudes por minuto) segundos.
const LIST_INTERVAL_MS = (60 / LIST_RATE_PER_MIN) * 1000;
const GET_INTERVAL_MS = (60 / GET_RATE_PER_MIN) * 1000;
const UPDATE_INTERVAL_MS = (60 / UPDATE_RATE_PER_MIN) * 1000;
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
// Realiza la solicitud, luego espera el intervalo de esta operación antes de regresar.
async function throttledFetch(url, options, intervalMs) {
const response = await fetch(url, options);
await sleep(intervalMs);
return response;
}
async function listEntries(universe, dataStore) {
const listPath = `universes/${universe}/data-stores/${dataStore}/entries`;
const url = baseUrl + listPath;
const response = await throttledFetch(url, {
headers: { [apiHeaderKey]: apiKey }
}, LIST_INTERVAL_MS);
return response.json();
}
async function getEntry(path) {
const url = baseUrl + path;
const response = await throttledFetch(url, {
headers: { [apiHeaderKey]: apiKey }
}, GET_INTERVAL_MS);
return response.json();
}
async function updateEntry(path, payload) {
const url = baseUrl + path;
const response = await throttledFetch(url, {
method: 'PATCH',
headers: {
[apiHeaderKey]: apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload) // El cuerpo debe ser una cadena
}, UPDATE_INTERVAL_MS);
return response;
}
(async () => {
try {
const entries = await listEntries(universeId, dataStoreId);
for (const entry of entries.dataStoreEntries) {
const path = entry.path;
console.log(`\nProcesando entrada: ${path}`);
const currentData = await getEntry(path);
currentData.value.currency += 10;
const payload = { value: currentData.value };
const updateResponse = await updateEntry(path, payload);
console.log(`Estado: ${updateResponse.status}`);
console.log(`Respuesta: ${await updateResponse.text()}`);
}
} catch (error) {
console.error('Ocurrió un error durante la ejecución:', error);
}
})();Límites del servidor
Cada servidor tiene un límite de tasa configurable para cada tipo de solicitud, basado en el número de jugadores en ese servidor. Los servidores reciben un impulso de presupuesto de solicitud adicional de una sola vez cuando se crean por primera vez. Usa GetRequestBudgetForRequestType() para confirmar el número de solicitudes de tienda de datos que el servidor actual puede hacer en cualquier momento dado.
Estos límites son configurables por el creador usando la API SetRateLimitForRequestType(). Usando esta API, un creador puede configurar sus propios límites de tasa de tiendas de datos para cada tipo de solicitud.
Los siguientes límites de tasa por defecto se aplican si la API no se llama:
Tiendas de datos estándar
| Tipo de solicitud | DataStoreRequestType Enum | API del servidor de juego | Solicitudes por minuto |
|---|---|---|---|
| Leer | StandardRead | GetAsync() GetVersionAsync() GetVersionAtTimeAsync() UpdateAsync() | 60 + numPlayers × 40 |
| Escribir | StandardWrite | SetAsync() IncrementAsync() UpdateAsync() | 60 + numPlayers × 40 |
| Listar | StandardList | ListDataStoresAsync() ListKeysAsync() ListVersionsAsync() | 5 + numPlayers × 2 |
| Eliminar | StandardRemove | RemoveAsync() | 60 + numPlayers × 40 |
| RemoveVersion (Obsoleto) | RemoveVersionAsync | RemoveVersionAsync() | 5 + numPlayers × 2 |
Tiendas de datos ordenadas
| Tipo de solicitud | DataStoreRequestType Enum | API del servidor de juego | Solicitudes por minuto |
|---|---|---|---|
| Leer | OrderedRead | GetAsync() UpdateAsync() | 60 + numPlayers × 40 |
| Escribir | OrderedWrite | SetAsync() IncrementAsync() UpdateAsync() | 30 + numPlayers × 5 |
| Listar | OrderedList | GetSortedAsync() | 5 + numPlayers × 2 |
| Eliminar | OrderedRemove | RemoveAsync() | 30 + numPlayers × 5 |
Límites de datos
Las tiendas de datos limitan cuánto se puede usar por entrada.
El nombre de la tienda de datos, el nombre de la clave y el alcance deben estar todos por debajo de cierta longitud de carácter. Utiliza string.len() para comprobar su longitud.
Los datos (valor de clave) también se almacenan como una cadena, independientemente de su tipo inicial. Puedes comprobar el tamaño de los datos con la función JSONEncode(), que convierte datos de Luau en una tabla JSON serializada.
| Componente | Número máximo de caracteres |
|---|---|
| Nombre de la tienda de datos | 50 |
| Nombre de la clave | 50 |
| Alcance | 50 |
| Datos (valor de clave) | 4,194,304 por clave |
Límites de metadatos
Límites al número de caracteres en los metadatos definidos por el usuario.
| Componente | Número máximo de caracteres |
|---|---|
| Nombre de clave | 50 |
| Valor | 250 |
| Pares clave-valor | 300 |
Límites de rendimiento
Los límites de rendimiento por clave aseguran que el rendimiento sea óptimo en los servidores de Roblox. Cada límite se aplica a cada clave individual en todos los servidores en una experiencia y se actualiza con el tiempo.
Roblox examina el uso de la cuota asociada a la clave durante los últimos 60 segundos. Si el uso, incluida la solicitud actual, está dentro del límite de rendimiento, la solicitud es aprobada. Si el uso supera el límite, la solicitud es denegada.
| Tipo de solicitud | API del servidor de juego | API de Open Cloud | Límite |
|---|---|---|---|
| Leer | GetAsync() GetVersionAsync() GetVersionAtTimeAsync() ListVersionsAsync() UpdateAsync() | Obtener entrada de la tienda de datos | 25 MB por minuto |
| Escribir | SetAsync() IncrementAsync() UpdateAsync() RemoveAsync() | Crear, actualizar, incrementar, eliminar entrada de la tienda de datos | 4 MB por minuto |
Además de los límites de rendimiento mencionados, Roblox organiza datos en particiones basadas en un esquema interno. Como resultado, cuando el servidor backend recibe un alto volumen de solicitudes a la misma tienda de datos, puede resultar en una mayor limitación. Independientemente de la causa, la limitación se manifiesta como errores DatastoreThrottled o KeyThrottled, dependiendo de si se excedió el límite de rendimiento para una sola tienda de datos o una clave. Estos mensajes de error se aplican tanto a tiendas de datos ordenadas como estándar.
Límites de almacenamiento
Para mantener el almacenamiento estable y escalable, las tiendas de datos utilizan un límite a nivel de juego sobre tu uso de almacenamiento.
Este límite consiste en una asignación base para cada juego más una asignación adicional basada en el número de usuarios de por vida. Un usuario de por vida es cualquier usuario que se haya unido a tu juego al menos una vez.
El límite de almacenamiento se calcula utilizando la siguiente fórmula Límite total de almacenamiento de la última versión = 500 MB + 1 MB × recuento de usuarios de por vida.
El uso de almacenamiento se mide utilizando el tamaño comprimido de la última versión de cada clave. Las tiendas de datos comprimen automáticamente tus datos antes del almacenamiento, así que evita comprimirlos tú mismo. La compresión previa agrega una sobrecarga innecesaria de CPU y puede reducir la efectividad de la compresión incorporada de las tiendas de datos. Al almacenar datos no comprimidos, te beneficias automáticamente de las mejoras en los algoritmos de compresión de Roblox y futuras optimizaciones basadas en esquemas.
Solo la última versión de cada clave cuenta hacia tu uso de almacenamiento. Las claves eliminadas y las versiones reemplazadas, aunque aún son accesibles a través de APIs de versión durante su período de retención, no cuentan hacia tu uso de almacenamiento. Sin embargo, las tiendas de datos eliminadas a través del método Open Cloud DeleteDataStore continúan contando hacia el uso de almacenamiento durante su período de procesamiento de eliminación de 30 días, hasta que sean eliminadas permanentemente.