As solicitações que você faz aos armazenamentos de dados podem falhar devido a conectividade ruim ou outros problemas. Para lidar com erros e retornar mensagens com um código de erro, envolva as funções do armazenamento de dados em pcall().
Uma chamada de gravação que falhou, como UpdateAsync(), significa que o servidor do jogo não recebeu uma resposta bem-sucedida. Isso não garante sempre que a gravação no backend não ocorreu. Em alguns cenários de falha, o estado final da gravação pode ser desconhecido para o chamador até que seja verificado com uma leitura subsequente sem cache.
Referência de códigos de erro
| Código de erro | Nome do erro | Mensagem de erro | Anotações | |
|---|---|---|---|---|
| 101 | KeyNameEmpty | O nome da chave não pode estar vazio. | Verifique se a chave inserida na função do armazenamento de dados é uma string vazia. | |
| 102 | KeyNameLimit | O nome da chave excede o limite de 50 caracteres. | Verifique se a chave inserida na função do armazenamento de dados excede um comprimento de 50. | |
| 103 | ValueNotAllowed | Não é permitido X em DataStore. | Uma função de atualização ruim retornou um valor do tipo X. | |
| 104 | CantStoreValue | Não é possível armazenar X em DataStore. | A função de atualização retornou um valor do tipo X que não foi serializado. | |
| 105 | ValueTooLarge | O valor serializado excede o limite de X. | Se você estiver definindo um valor com SetAsync() ou UpdateAsync(), o comprimento serializado do valor não pode exceder o tamanho X. Para verificar o comprimento serializado dos dados, use JSONEncode(). | |
| 106 | MaxValueInvalid | MaxValue deve ser um número inteiro. | Se você estiver passando um valor máximo para GetSortedAsync() para um OrderedDataStore, deve ser um número inteiro. | |
| 106 | MinValueInvalid | MinValue deve ser um número inteiro. | Se você estiver passando um valor mínimo para GetSortedAsync() para um OrderedDataStore, deve ser um número inteiro. | |
| 106 | PageSizeGreater | PageSize deve estar dentro de uma faixa pré-definida. | O tamanho mínimo da página para um OrderedDataStore é 1. | |
| 106 | PageSizeLesser | PageSize deve estar dentro de uma faixa pré-definida. | O tamanho máximo da página para um OrderedDataStore é 100. | |
| 107 | MinMaxOrderInvalid | MaxValue deve ser maior ou igual a MinValue. | O valor máximo deve ser maior ou igual ao valor mínimo para GetSortedAsync(). | |
| 301 | GetAsyncThrottle | Solicitação GetAsync descartada. A solicitação foi desacelerada, mas a fila estava cheia. | A solicitação GetAsync() excedeu o tamanho máximo da fila e o Roblox não consegue processar as solicitações na taxa de transferência atual. | |
| 302 | SetAsyncThrottle | Solicitação SetAsync descartada. A solicitação foi desacelerada, mas a fila estava cheia. | A solicitação SetAsync() excedeu o tamanho máximo da fila e o Roblox não consegue processar as solicitações na taxa de transferência atual. | |
| 303 | IncreAsyncThrottle | Solicitação IncrementAsync descartada. A solicitação foi desacelerada, mas a fila estava cheia. | A solicitação IncrementAsync() excedeu o tamanho máximo da fila e o Roblox não consegue processar as solicitações na taxa de transferência atual. | |
| 304 | UpdateAsyncThrottle | Solicitação UpdateAsync descartada. A solicitação foi desacelerada, mas a fila estava cheia. | A solicitação UpdateAsync() excedeu o tamanho máximo da fila e o Roblox não consegue processar as solicitações na taxa de transferência atual. | |
| 304 | TransformThrottle | Solicitação UpdateAsync descartada. A solicitação foi desacelerada, mas a fila estava cheia. | A solicitação UpdateAsync() excedeu o tamanho máximo da fila e o Roblox não consegue processar as solicitações na taxa de transferência atual. | |
| 305 | GetSortedThrottle | Solicitação GetSorted descartada. A solicitação foi desacelerada, mas a fila estava cheia. | A solicitação GetSortedAsync() excedeu o tamanho máximo da fila e o Roblox não consegue processar as solicitações na taxa de transferência atual. | |
| 306 | RemoveAsyncThrottle | Solicitação RemoveAsync descartada. A solicitação foi desacelerada, mas a fila estava cheia. | A solicitação RemoveAsync() excedeu o tamanho máximo da fila e o Roblox não consegue processar as solicitações na taxa de transferência atual. | |
| 401 | DataModelNoAccess | A solicitação falhou. DataModel é inacessível enquanto a experiência está encerrando. | DataModel não está inicializado porque a experiência está encerrando. | |
| 402 | LuaWebSrvsNoAccess | A solicitação falhou. LuaWebService é inacessível enquanto a experiência está encerrando. | LuaWebService não está inicializado porque a experiência está encerrando. | |
| 403 | StudioAccessToApisNotAllowed | Não é possível gravar no DataStore do Studio porque o acesso à API não está habilitado. | O acesso à API deve estar ativo para usar armazenamentos de dados no Studio. | |
| 404 | InternalError | OrderedDataStore não existe. | O OrderedDataStore associado a esta solicitação não foi encontrado. Isso pode ser um sinal de corrupção de dados. Tente novamente mais tarde. | |
| 501 | InternalError | Não é possível analisar a resposta porque os dados podem estar corrompidos. | O servidor não conseguiu analisar a resposta à sua solicitação. Isso pode ser um sinal de corrupção de dados. Tente novamente mais tarde. | |
| 502 | RequestRejected | Os serviços de API rejeitaram a solicitação com erro X. | Erro X ocorreu ao processar nos servidores do Roblox. Tente novamente mais tarde. | |
| 503 | InternalError | A solicitação do armazenamento de dados foi bem-sucedida, mas a chave não foi encontrada. | A chave solicitada não foi encontrada no armazenamento de dados. Isso pode ser um sinal de corrupção de dados. Tente novamente mais tarde. | |
| 504 | InternalError | A solicitação do armazenamento de dados foi bem-sucedida, mas a resposta não foi formatada corretamente. | O servidor não conseguiu analisar a resposta à sua solicitação. Isso pode ser um sinal de corrupção de dados. Tente novamente mais tarde. | |
| 505 | InternalError | A solicitação do OrderedDataStore foi bem-sucedida, mas a resposta não foi formatada corretamente. | O servidor não conseguiu analisar a resposta à sua solicitação OrderedDataStore. Isso pode ser um sinal de corrupção de dados. Tente novamente mais tarde. | |
| 509 | OperationNotAllowed | As operações do armazenamento de dados estão bloqueadas enquanto executam em um RCC Pessoal para evitar possível corrupção de dados. | As gravações do armazenamento de dados estão bloqueadas nos canais RCC privados. | |
| 511 | AttributeSizeTooLarge | O tamanho do atributo de metadados excede o limite de X. | O tamanho dos metadados serializados excede o limite de X. O valor X é dinâmico. Se o tamanho mudar, o valor também mudará. | |
| 512 | UserIdLimitExceeded | O tamanho de UserID excede o limite de X. | O comprimento do array de IDs de usuário fornecido excede o limite de X. | |
| 513 | AttributeFormatError | O formato do atributo userId é inválido. | O ID do usuário fornecido não é um número. | |
| 513 | AttributeFormatError | O formato do atributo de metadados é inválido. | Os metadados não são uma tabela. | |
| GetVersionAsyncThrottle | Solicitação GetVersionAsync descartada. A solicitação foi desacelerada. | A solicitação GetVersionAsync() excedeu o tamanho máximo da fila e o Roblox não consegue processar as solicitações na taxa de transferência atual. | ||
| GetVersionAtTimeAsyncThrottle | Solicitação GetVersionAtTimeAsync descartada. A solicitação foi desacelerada. | A solicitação GetVersionAtTimeAsync() excedeu o tamanho máximo da fila e o Roblox não consegue processar as solicitações na taxa de transferência atual. | ||
| ListDataStoresAsyncThrottle | Solicitação ListDataStoresAsync descartada. A solicitação foi desacelerada. | A solicitação ListDataStoresAsync() excedeu o tamanho máximo da fila e o Roblox não consegue processar as solicitações na taxa de transferência atual. | ||
| ListKeysAsyncThrottle | Solicitação ListKeysAsync descartada. A solicitação foi desacelerada. | A solicitação ListKeysAsync() excedeu o tamanho máximo da fila e o Roblox não consegue processar as solicitações na taxa de transferência atual. | ||
| ListVersionsAsyncThrottle | Solicitação ListVersionsAsync descartada. A solicitação foi desacelerada. | A solicitação ListVersionsAsync() excedeu o tamanho máximo da fila e o Roblox não consegue processar as solicitações na taxa de transferência atual. | ||
| RemoveVersionAsyncThrottle | Solicitação RemoveVersionAsync descartada. A solicitação foi desacelerada. | A solicitação RemoveVersionAsync() excedeu o tamanho máximo da fila e o Roblox não consegue processar as solicitações na taxa de transferência atual. | ||
| InvalidTimestamp | O timestamp deve ser positivo e não mais que dez minutos no futuro. | O timestamp fornecido para GetVersionAtTimeAsync() não era válido. | ||
| StandardReadExperienceThrottled | Solicitação StandardRead foi desacelerada pelos limites da experiência. | Uma solicitação para GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), ou a leitura de UpdateAsync() em um armazenamento de dados padrão excedeu o limite de taxa da experiência StandardRead. | ||
| StandardWriteExperienceThrottled | Solicitação StandardWrite foi desacelerada pelos limites da experiência. | Uma solicitação para SetAsync(), IncrementAsync(), ou a gravação de UpdateAsync() em um armazenamento de dados padrão excedeu o limite de taxa da experiência StandardWrite. | ||
| StandardListExperienceThrottled | Solicitação StandardList foi desacelerada pelos limites da experiência. | Uma solicitação para ListKeysAsync(), ListVersionsAsync(), ou ListDataStoresAsync() em armazenamentos de dados padrão excedeu o limite de taxa da experiência StandardList. | ||
| StandardRemoveExperienceThrottled | Solicitação StandardRemove foi desacelerada pelos limites da experiência. | Uma solicitação para RemoveAsync() em um armazenamento de dados padrão excedeu o limite de taxa da experiência StandardRemove. | ||
| OrderedReadExperienceThrottled | Solicitação OrderedRead foi desacelerada pelos limites da experiência. | Uma solicitação para GetAsync() ou a leitura de UpdateAsync() em um armazenamento de dados ordenado excedeu o limite de taxa da experiência OrderedRead. | ||
| OrderedWriteExperienceThrottled | Solicitação OrderedWrite foi desacelerada pelos limites da experiência. | Uma solicitação para SetAsync(), IncrementAsync(), ou a gravação de UpdateAsync() em um armazenamento de dados ordenado excedeu o limite de taxa da experiência OrderedWrite. | ||
| OrderedListExperienceThrottled | Solicitação OrderedList foi desacelerada pelos limites da experiência. | Uma solicitação para GetSortedAsync() em um armazenamento de dados ordenado excedeu o limite de taxa da experiência OrderedList. | ||
| OrderedRemoveExperienceThrottled | Solicitação OrderedRemove foi desacelerada pelos limites da experiência. | Uma solicitação para RemoveAsync() em um armazenamento de dados ordenado excedeu o limite de taxa da experiência OrderedRemove. | ||
| StandardReadGameServerThrottled | Solicitação StandardRead foi desacelerada pelos limites do servidor de jogos ou a fila da solicitação estava cheia. | Uma solicitação para GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), ou a leitura de UpdateAsync() em um armazenamento de dados padrão excedeu o limite de taxa do servidor de jogos StandardRead. | ||
| StandardWriteGameServerThrottled | Solicitação StandardWrite foi desacelerada pelos limites do servidor de jogos ou a fila da solicitação estava cheia. | Uma solicitação para SetAsync(), IncrementAsync(), ou a gravação de UpdateAsync() em um armazenamento de dados padrão excedeu o limite de taxa do servidor de jogos StandardWrite. | ||
| StandardListGameServerThrottled | Solicitação StandardList foi desacelerada pelos limites do servidor de jogos ou a fila da solicitação estava cheia. | Uma solicitação para ListKeysAsync(), ListVersionsAsync(), ou ListDataStoresAsync() em armazenamentos de dados padrão excedeu o limite de taxa do servidor de jogos StandardList. | ||
| StandardRemoveGameServerThrottled | Solicitação StandardRemove foi desacelerada pelos limites do servidor de jogos ou a fila da solicitação estava cheia. | Uma solicitação para RemoveAsync() em um armazenamento de dados padrão excedeu o limite de taxa do servidor de jogos StandardRemove. | ||
| OrderedReadGameServerThrottled | Solicitação OrderedRead foi desacelerada pelos limites do servidor de jogos ou a fila da solicitação estava cheia. | Uma solicitação para GetAsync() ou a leitura de UpdateAsync() em um armazenamento de dados ordenado excedeu o limite de taxa do servidor de jogos OrderedRead. | ||
| OrderedWriteGameServerThrottled | Solicitação OrderedWrite foi desacelerada pelos limites do servidor de jogos ou a fila da solicitação estava cheia. | Uma solicitação para SetAsync(), IncrementAsync(), ou a gravação de UpdateAsync() em um armazenamento de dados ordenado excedeu o limite de taxa do servidor de jogos OrderedWrite. | ||
| OrderedListGameServerThrottled | Solicitação OrderedList foi desacelerada pelos limites do servidor de jogos ou a fila da solicitação estava cheia. | Uma solicitação para GetSortedAsync() em um armazenamento de dados ordenado excedeu o limite de taxa do servidor de jogos OrderedList. | ||
| OrderedRemoveGameServerThrottled | Solicitação OrderedRemove foi desacelerada pelos limites do servidor de jogos ou a fila da solicitação estava cheia. | Uma solicitação para RemoveAsync() em um armazenamento de dados ordenado excedeu o limite de taxa do servidor de jogos OrderedRemove. |
Códigos de erro do servidor
| Nome do erro | Mensagem de erro | Anotações |
|---|---|---|
| DatastoreDeleted | O armazenamento de dados foi excluído. | Uma operação no armazenamento de dados não pôde ocorrer porque o armazenamento de dados foi excluído anteriormente. |
| DatastoreThrottled | A taxa de solicitações excede o máximo permitido para o datastore. | Solicitações em excesso foram enviadas a um único armazenamento de dados. |
| InternalServerError | Ocorreu um erro interno do servidor. | Erro ocasional nos servidores do Roblox. Tente novamente, idealmente com tentativas em intervalos crescentes. |
| InvalidExclusiveStartKey | A chave inicial exclusiva fornecida não é válida. | A chave inicial exclusiva (cursor) fornecida a uma operação de listagem, como ListKeysAsync(), não é válida. |
| InvalidPlace | O lugar fornecido é inválido. | Sem ID de universo correspondente para o lugar. Tente novamente mais tarde. |
| InvalidTarget | O alvo fornecido é inválido. | O nome da chave do armazenamento de dados ordenado excede o limite de 50 caracteres. |
| InvalidUniverse | O universo fornecido é inválido. | Sem ID de lugar correspondente para o universo. Tente novamente mais tarde. |
| InvalidUserIds | Os IDs de usuário fornecidos têm um formato inválido. | Não foi possível analisar os IDs de usuário. |
| KeyThrottled | A taxa de solicitações excede o máximo permitido para a chave. | A taxa de solicitações excede a taxa de solicitação máxima permitida para uma única chave. |
| KeyNotFound | A chave solicitada não existe. | A chave não existe. |
| N/A | Não há páginas para avançar. | Esse erro ocorre quando você chama Pages:AdvanceToNextPageAsync() na última página. |
| StandardReadExperienceThrottled | A taxa de solicitações de leitura padrão excede o máximo permitido para a experiência. | Uma solicitação para GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), ou a leitura de UpdateAsync() em um armazenamento de dados padrão excedeu o limite de taxa de leitura padrão da experiência. |
| StandardWriteExperienceThrottled | A taxa de solicitações de gravação padrão excede o máximo permitido para a experiência. | Uma solicitação para SetAsync(), IncrementAsync(), ou a gravação de UpdateAsync() em um armazenamento de dados padrão excedeu o limite de taxa de gravação padrão da experiência. |
| StandardListExperienceThrottled | A taxa de solicitações de listagem padrão excede o máximo permitido para a experiência. | Uma solicitação para ListKeysAsync(), ListVersionsAsync(), ou ListDataStoresAsync() em armazenamentos de dados padrão excedeu o limite de taxa de listagem padrão da experiência. |
| StandardRemoveExperienceThrottled | A taxa de solicitações de remoção padrão excede o máximo permitido para a experiência. | Uma solicitação para RemoveAsync() em um armazenamento de dados padrão excedeu o limite de taxa de remoção padrão da experiência. |
| OrderedReadExperienceThrottled | A taxa de solicitações de leitura ordenada excede o máximo permitido para a experiência. | Uma solicitação para GetAsync() ou a leitura de UpdateAsync() em um armazenamento de dados ordenado excedeu o limite de taxa de leitura ordenada da experiência. |
| OrderedWriteExperienceThrottled | A taxa de solicitações de gravação ordenada excede o máximo permitido para a experiência. | Uma solicitação para SetAsync(), IncrementAsync(), ou a gravação de UpdateAsync() em um armazenamento de dados ordenado excedeu o limite de taxa de gravação ordenada da experiência. |
| OrderedListExperienceThrottled | A taxa de solicitações de listagem ordenada excede o máximo permitido para a experiência. | Uma solicitação para GetSortedAsync() em um armazenamento de dados ordenado excedeu o limite de taxa de listagem ordenada da experiência. |
| OrderedRemoveExperienceThrottled | A taxa de solicitações de remoção ordenada excede o máximo permitido para a experiência. | Uma solicitação para RemoveAsync() em um armazenamento de dados ordenado excedeu o limite de taxa de remoção ordenada da experiência. |
Limites
Modelos de dados têm limites. Se uma experiência exceder esses limites, o serviço desacelera automaticamente o uso do armazenamento de dados da experiência e causa futuras solicitações a serem colocadas em uma das seguintes filas:
- Definir
- Conjunto ordenado
- Obter
- Obter ordenado
Solicitações em uma fila são tratadas na ordem em que são recebidas. A função chamada continua a ceder enquanto sua solicitação ainda estiver na fila. Se a chave do armazenamento de dados estiver desacelerada, a solicitação é colocada em uma fila, mas é temporariamente ignorada.
Cada fila tem um limite de 30 solicitações. Quando o limite de uma fila é atingido, as solicitações falham com um código de erro na faixa de 301-306, indicando que as solicitações foram totalmente descartadas.
Limites de acesso
Os armazenamentos de dados estão sujeitos a limites de experiência e níveis de servidor. Limites de nível de experiência escalam com o número total de usuários concorrentes na experiência, enquanto os limites de nível de servidor são configuráveis e devem ser usados como uma ferramenta pelo criador.
Limites de experiência
Cada experiência tem um certo número de solicitações de armazenamento de dados permitidas com base no tipo de armazenamento de dados, tipo de solicitação e número de usuários concorrentes. Para cada tipo de armazenamento de dados e tipo de solicitação, o limite é compartilhado entre todas as funções listadas.
- UpdateAsync() consome tanto do orçamento de solicitações de leitura quanto do orçamento de solicitações de gravação. Uma única chamada diminuirá ambos os limites.
- Servidores de jogos e Open Cloud compartilham um orçamento; o tráfego do Open Cloud pode ser desacelerado pelo uso dentro da experiência (e vice-versa). Veja Controlar limites de taxa para mais orientações.
Armazenamentos de dados padrão
| Tipo de solicitação | API do servidor de jogos | API do Open Cloud | Limites compartilhados (solicitações por minuto) |
|---|---|---|---|
| Leitura | GetAsync() GetVersionAsync() GetVersionAtTimeAsync() UpdateAsync() | Obter entrada do armazenamento de dados | 300 + usuáriosConcorrentes × 40 |
| Gravação | SetAsync() IncrementAsync() UpdateAsync() | Criar, atualizar, incrementar entrada do armazenamento de dados | 300 + usuáriosConcorrentes × 20 |
| Listar | ListDataStoresAsync() ListKeysAsync() ListVersionsAsync() | Listar armazenamentos de dados, listar entradas de armazenamento de dados, listar revisões de entradas de armazenamento de dados | 300 + usuáriosConcorrentes × 2 |
| Remover | RemoveAsync() | Excluir entrada do armazenamento de dados, excluir armazenamento de dados, restaurar armazenamento de dados | 300 + usuáriosConcorrentes × 40 |
Armazenamentos de dados ordenados
| Tipo de solicitação | API do servidor de jogos | API do Open Cloud | Limites compartilhados (solicitações por minuto) |
|---|---|---|---|
| Leitura | GetAsync() UpdateAsync() | Obter entrada do armazenamento de dados ordenado | 300 + usuáriosConcorrentes × 40 |
| Gravação | SetAsync() IncrementAsync() UpdateAsync() | Criar, atualizar, incrementar entrada do armazenamento de dados ordenado | 300 + usuáriosConcorrentes × 20 |
| Listar | GetSortedAsync() | Listar entradas do armazenamento de dados ordenado | 300 + usuáriosConcorrentes × 2 |
| Remover | RemoveAsync() | Excluir entrada do armazenamento de dados ordenado | 300 + usuáriosConcorrentes × 40 |
Controlar limites de taxa
Como as solicitações do Open Cloud e do servidor de jogos são compartilhadas, é importante controlar independentemente quanto cada um pode consumir do orçamento.
Servidor de jogos
Servidores individuais têm limites embutidos, conforme descrito acima. Use uma combinação de SetRateLimitForRequestType() e GetRequestBudgetForRequestType() para manter um controle fino sobre a contribuição de servidores individuais para o orçamento total.
Open Cloud
As solicitações do Open Cloud requerem uma solução externa de limitação de taxa. Recomendamos uma das seguintes abordagens:
- (Simples) Adicione um pequeno tempo limite após cada solicitação, especialmente se estiver chamando a mesma API em um loop contínuo. Defina esse tempo limite igual a 60 / (consumo desejado por minuto) segundos, como um limite superior. Observe que essa abordagem não permite que as solicitações sejam enviadas em explosões.
- (Robusta) Implemente um limitador de taxa local usando a estratégia de balde furado.
Os seguintes exemplos de código em Node.js incluem implementações de referência.
const apiKey = process.env.API_KEY;
if (!apiKey) {
throw new Error('A variável de ambiente API_KEY não está definida.');
}
const apiHeaderKey = 'x-api-key';
const universeId = '';
const dataStoreId = 'Inventário';
const baseUrl = 'https://apis.roblox.com/cloud/v2/';
// --- Configuração de limitação de taxa por operação (solicitações por minuto) ---
const LIST_RATE_PER_MIN = 60;
const GET_RATE_PER_MIN = 120;
const UPDATE_RATE_PER_MIN = 60;
// Intervalo superior para cada operação: 60 / (solicitações por min) 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 a solicitação, em seguida aguarda o intervalo próprio desta operação antes de retornar.
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) // O corpo deve ser uma string
}, 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(`\nProcessando entrada: ${path}`);
const currentData = await getEntry(path);
currentData.value.currency += 10;
const payload = { value: currentData.value };
const updateResponse = await updateEntry(path, payload);
console.log(`Status: ${updateResponse.status}`);
console.log(`Resposta: ${await updateResponse.text()}`);
}
} catch (error) {
console.error('Ocorreu um erro durante a execução:', error);
}
})();Limites do servidor
Cada servidor tem um limite de taxa configurável para cada tipo de solicitação, com base no número de jogadores naquele servidor. Os servidores recebem um estouro inicial único de orçamento adicional de solicitações quando são criados inicialmente. Use GetRequestBudgetForRequestType() para confirmar o número de solicitações de armazenamento de dados que o servidor atual pode fazer a qualquer momento.
Esses limites são configuráveis pelo criador usando a API SetRateLimitForRequestType(). Usando esta API, um criador pode configurar seus próprios limites de taxa de armazenamento de dados para cada tipo de solicitação.
Os seguintes limites padrão de taxa se aplicam se a API não for chamada:
Armazenamentos de dados padrão
| Tipo de solicitação | DataStoreRequestType Enum | API do servidor de jogos | Solicitações por minuto |
|---|---|---|---|
| Leitura | StandardRead | GetAsync() GetVersionAsync() GetVersionAtTimeAsync() UpdateAsync() | 60 + numPlayers × 40 |
| Gravação | StandardWrite | SetAsync() IncrementAsync() UpdateAsync() | 60 + numPlayers × 40 |
| Listar | StandardList | ListDataStoresAsync() ListKeysAsync() ListVersionsAsync() | 5 + numPlayers × 2 |
| Remover | StandardRemove | RemoveAsync() | 60 + numPlayers × 40 |
| RemoverVersão (Depreciado) | RemoveVersionAsync | RemoveVersionAsync() | 5 + numPlayers × 2 |
Armazenamentos de dados ordenados
| Tipo de solicitação | DataStoreRequestType Enum | API do servidor de jogos | Solicitações por minuto |
|---|---|---|---|
| Leitura | OrderedRead | GetAsync() UpdateAsync() | 60 + numPlayers × 40 |
| Gravação | OrderedWrite | SetAsync() IncrementAsync() UpdateAsync() | 30 + numPlayers × 5 |
| Listar | OrderedList | GetSortedAsync() | 5 + numPlayers × 2 |
| Remover | OrderedRemove | RemoveAsync() | 30 + numPlayers × 5 |
Limites de dados
Os armazenamentos de dados limitam quanto dados podem ser usados por entrada.
O nome do armazenamento de dados, o nome da chave e o escopo devem estar todos abaixo de um certo comprimento de caracteres. Use string.len() para verificar o comprimento deles.
Os dados (valor da chave) também são armazenados como uma string, independentemente de seu tipo inicial. Você pode verificar o tamanho dos dados com a função JSONEncode(), que converte dados Luau em uma tabela JSON serializada.
| Componente | Número máximo de caracteres |
| Nome do armazenamento de dados | 50 |
| Nome da chave | 50 |
| Escopo | 50 |
| Dados (valor da chave) | 4.194.304 por chave |
Limites de metadados
Limites ao número de caracteres nos metadados definidos pelo usuário.
| Componente | Número máximo de caracteres |
|---|---|
| Nome da chave | 50 |
| Valor | 250 |
| Pares chave-valor | 300 |
Limites de throughput
Limites de throughput por chave garantem que o desempenho seja otimizado nos servidores do Roblox. Cada limite se aplica a cada chave individual em todos os servidores de uma experiência e se atualiza ao longo do tempo.
O Roblox examina o uso da cota associada à chave nos últimos 60 segundos. Se o uso, incluindo a solicitação atual, estiver dentro do limite de throughput, a solicitação é aprovada. Se o uso exceder o limite, a solicitação é negada.
| Tipo de solicitação | API do servidor de jogos | API do Open Cloud | Limite |
|---|---|---|---|
| Leitura | GetAsync() GetVersionAsync() GetVersionAtTimeAsync() ListVersionsAsync() UpdateAsync() | Obter entrada do armazenamento de dados | 25 MB por minuto |
| Gravação | SetAsync() IncrementAsync() UpdateAsync() RemoveAsync() | Criar, atualizar, incrementar, remover entrada do armazenamento de dados | 4 MB por minuto |
Além dos limites de throughput acima, o Roblox organiza dados em partições com base em um esquema interno. Como resultado, quando o servidor de backend recebe um alto volume de solicitações ao mesmo armazenamento de dados, isso pode resultar em mais desacelerações. Independentemente da causa, a desaceleração se manifesta como erros DatastoreThrottled ou KeyThrottled, dependendo se o limite de throughput foi excedido para um único armazenamento de dados ou uma chave. Essas mensagens de erro se aplicam tanto a armazenamentos de dados ordenados quanto padrão.
Limites de armazenamento
Para manter o armazenamento estável e escalável, os armazenamentos de dados usam um limite de nível de jogo sobre seu uso de armazenamento.
Esse limite consiste em uma alocação base para cada jogo mais uma alocação adicional com base no número de usuários vitalícios. Um usuário vitalício é qualquer usuário que tenha ingressado em seu jogo pelo menos uma vez.
O limite de armazenamento é calculado usando a seguinte fórmula Limite total de armazenamento de versão mais recente = 500 MB + 1 MB × contagem de usuários vitalícios.
O uso de armazenamento é medido usando o tamanho comprimido da versão mais recente de cada chave. Os armazenamentos de dados comprimem automaticamente seus dados antes de armazená-los, portanto, evite pré-comprimir os dados. A pré-compressão adiciona sobrecarga desnecessária da CPU e pode reduzir a eficácia da compressão interna dos dados. Ao armazenar dados não comprimidos, você se beneficia automaticamente de melhorias nos algoritmos de compressão do Roblox e em futuras otimizações com base em esquemas.
Apenas a versão mais recente de cada chave conta para o uso de armazenamento. Chaves excluídas e versões superadas, embora ainda acessíveis por meio das APIs de versão durante seu período de retenção, não contam para o uso do armazenamento. No entanto, os armazenamentos de dados excluídos através do método Open Cloud DeleteDataStore continuam a contar para o uso de armazenamento durante seu período de processamento de exclusão de 30 dias, até que sejam removidos permanentemente.