Apex Academy
Módulo 4·04·30 min

Governor Limits: qué se cuenta y por qué

Los topes que Salesforce pone a cada transacción, por qué existen, cuáles vas a tocar primero y cómo medir lo que gasta tu código antes de que lo mida producción.

En Admin esEl correo de error de Flow que dice «Too many SOQL queries: 101»

✓ En esta sub-lección

  1. 01Explicar por qué existen los governor limits y qué es una transacción.
  2. 02Recordar los límites que más se tocan: consultas, filas, DML, CPU y heap.
  3. 03Medir el consumo con la clase Limits.

La nutria: ¿Te acuerdas? · Repaso de la lección 3

¿Por qué en la tarea 3 la consulta y el update salieron del bucle?

Has oído hablar de los desde el Módulo 1. Ya tienes todo lo necesario para entenderlos de verdad: sabes qué es una consulta, qué es un DML y por qué un bucle puede multiplicarlos. Esta lección pone los números encima de la mesa.

La nutria: Ya te has cruzado con ellos

A mí me llegó más de una vez el correo «An error occurred with your … flow» con el texto «Too many SOQL queries: 101» o «Too many DML statements: 151». Si a ti también, ya conoces un governor limit. El Flow no tenía un fallo de lógica: hizo más viajes a la base de datos de los que la transacción permite. Apex juega exactamente con las mismas reglas, y con el mismo contador.

Por qué existen

Tu org no tiene servidores propios: comparte la infraestructura con miles de otras empresas. Es lo que Salesforce llama arquitectura . Si un código mal escrito de otra empresa pudiera acaparar la base de datos durante diez minutos, tu org se volvería lenta sin que tú hubieras hecho nada. Los governor limits son el reparto justo: cada transacción recibe un presupuesto, y quien lo supera se detiene sin molestar a los demás.

Qué es exactamente una transacción

Una es todo lo que ocurre a raíz de un mismo guardado: el trigger, los flows desencadenados por registro, las reglas de validación, las actualizaciones de campo, otros triggers que esos cambios disparen… Todo comparte el mismo presupuesto. Por eso tu trigger puede fallar por culpa de consultas que hizo un flow antes que él, y al revés. Los límites no son de tu código: son del guardado entero.

Los que vas a tocar primero

Límite por transacciónSíncronoAsíncrono (Módulo 9)Qué lo gasta
Consultas SOQL100200Cada [SELECT …] y cada Get Records
Filas devueltas por SOQL50.00050.000La suma de filas de todas las consultas
Instrucciones DML150150Cada insert/update/delete/upsert, tenga 1 o 200 registros
Filas procesadas por DML10.00010.000La suma de registros de todos los DML
Tiempo de CPU10 s60 sBucles, cálculos, flows, fórmulas…
Memoria (heap)6 MB12 MBListas, mapas y objetos que guardas
Búsquedas SOSL2020Cada [FIND …]
// empieza la transacción
Consultas SOQL0 / 100
Filas leídas0 / 50.000
Instrucciones DML0 / 150
Filas escritas0 / 10.000
CPU en ms (orientativo)0 / 10.000

Paso 1 de 6

Todos los contadores empiezan en cero en cada transacción.

Avanza línea a línea y mira qué contador sube con cada una: son los mismos que verás al final de cada log. La barra que se acerca al final es la que tienes que vigilar.

Fíjate en la diferencia entre instrucciones y filas. Un update de una lista de 200 cuentas es 1 instrucción DML y 200 filas. Por eso la bulkificación de la lección anterior funciona: no reduce los registros que guardas, reduce los viajes. 150 viajes se acaban enseguida; 10.000 filas dan para mucho.

Medir: la clase Limits

Apex
System.debug('Consultas: ' + Limits.getQueries() + ' de ' + Limits.getLimitQueries());
System.debug('DML: '       + Limits.getDmlStatements() + ' de ' + Limits.getLimitDmlStatements());
System.debug('Filas DML: ' + Limits.getDmlRows() + ' de ' + Limits.getLimitDmlRows());
System.debug('CPU (ms): '  + Limits.getCpuTime() + ' de ' + Limits.getLimitCpuTime());
Cada límite tiene su pareja: getX() dice cuánto llevas gastado y getLimitX() cuánto tienes. Son métodos static: no hace falta crear nada (Módulo 5).

La nutria: Leer el log como un Admin con lupa

Mi truco cuando un Flow fallaba por límites: ir al final del debug log. Ahí hay un bloque LIMIT_USAGE_FOR_NS con todos los contadores: «Number of SOQL queries: 3 out of 100». Ese bloque te dice quién se come el presupuesto. Es la misma información que la clase Limits, pero al final en lugar de en el momento que tú elijas.

La nutria: ¿Y por qué no un Flow? Porque Flow no te deja mirar el contador

En Flow, cuánto presupuesto llevas gastado solo lo ves en el debug log, cuando todo ha terminado o ya ha reventado. No hay ningún elemento que te diga «llevas 85 consultas» a mitad de camino; para eso hace falta una acción escrita en Apex. La clase Limits te lo dice en cualquier línea de tu código.