En enero, Vantegrate grabó una masterclass de los jueves con un tema que parece de mantenimiento y no lo es. Rendimiento en Salesforce no es un ajuste de última hora: es el costo de cada automatización chica que dejaron para después.
La clase se filmó el 8 de enero y la pueden ver completa en YouTube. Francisco Morales (Fran), Josué Mendoza (Josu) y Esti la armaron con anécdotas reales, sin nombrar clientes.
El equipo de Vantegrate lo dijo de entrada. Hoy vamos a ver errores que todos cometimos y cómo recortarlos a tiempo.
Josu arrancó con una premisa chiquita a propósito. Pequeñas desatenciones, empujadas por entregar valor ya, se convierten en una bola de nieve.
Lo provisorio que se queda para siempre
Fran metió la frase que duele porque es cierta. La técnica de "hago esta solución para salir del paso y después lo mejoro" casi nunca llega.
En la casa dejan algo con cinta una semana. En la org dejan un Flow que anda, y el "si funciona, no se toca" es una máxima que después les explota.
Josu lo dijo con el humor que todos reconocen. En esta parte del mundo eso se llama provisorio para siempre.
El usuario no ve el diseño. Ve un CPU time limit exceeded y no tiene idea qué es.
Eso aplica a Flow y a Apex por igual. Hoy, con herramientas de vibe coding, las buenas prácticas no son opcionales: hay que reglamentar el desarrollo, no solo el clic.
El requerimiento que cabe en una frase
Josu propuso un caso casi de manual. Una cuenta tiene muchos contactos, y en esa implementación cada cuenta tiene un manager.
Cuando cargan el manager, todos los contactos de esa cuenta tienen que pasar a su ownership. El owner del contacto es el manager de la cuenta (así de chiquito).
Tienen Apex, pero tratan de evitarlo. Workflow y Process Builder son viejísimos, así que nace un record-triggered Flow sobre cuenta.
El Flow corre al actualizar la cuenta y trabaja con registros relacionados. Primero hace un Get de contactos de esa cuenta; después itera, asigna el owner y actualiza adentro del loop.
Lo prueba, funciona y lo manda a producción porque lo pedían para ayer. En una org chica no pasa nada; cuando se llena, el Flow que andaba se vuelve el villano.
Sin entry conditions, el Flow corre de más
El primer olvido es de libro. El Flow corre cada vez que la cuenta se actualiza, no solo cuando cambia el manager.
Le tocan el nombre, el teléfono, cualquier campo. Invisible, esa automatización consume tiempo y recursos de la organización.
Josu fue directo. Ha visto orgs con más de 300 Flows sobre un solo objeto.
Todo empieza a comer CPU, a hacer queries, a actualizar, hasta que Salesforce dice basta. La primera regla es reducir el escenario al mínimo: la lógica corre solo cuando hace falta, nunca por las dudas.
Eduardo y Layton marcaron lo mismo en el chat. Si el Flow solo corre en update, un alta no replica el manager; hace falta set entry conditions cuando cambia el campo que importa.
Fran sumó experiencia de proyectos con muchas business units en la misma org. Una cuenta para una unidad dispara una automatización y para otra no.
Ahí los tipos de registro al frente ahorran romper todo cuando el negocio suma ideas. Carlos tiró el truco: en las condiciones pueden usar una fórmula con el Developer Name del record type.
Hay un segundo interruptor, más escondido, adentro de un Decision. Pueden ejecutar la rama siempre que el registro cumpla la condición, o solo cuando cambió y empezó a cumplirla.
Josu lo mostró con el manager nulo: si ya estaba cargado y alguien toca otro campo, el Decision no dispara Get, loop ni update. Fran lo llevó a un mail de oportunidad cerrada que se reenvía cuando editan la descripción.
Ese chequeo de abajo, el que casi no se mira, pide que el requerimiento se cumpla por primera vez, no cada vez que el registro se guarda.
Más de 50.000 registros: el Get que un día pincha
El Get de contactos parece inofensivo. Funciona hasta que Salesforce no les devuelve más de 50.000 registros en esa query.
Josu trajo un caso real: años asignando productos a listas de precios, y un día falló. Nadie había tocado nada; ya había más de 50.000 productos.
La solución de los quince minutos fue un LIMIT (dame hasta 50.000 y listo), y eso no es buena práctica: es tapar el termómetro. La regla de la clase fue otra: si puede pasar, va a pasar.
Update adentro del loop (y el subflow que finge)
Por cada contacto actualizado adentro del ciclo disparan un DML. Y todos los triggers de contacto empiezan a correr.
Es un record-triggered de cuenta que enciende el de contacto. Si esos contactos actualizan otros registros, la transacción se va de las manos.
La buena práctica es siempre la misma, en Flow y en Apex. El DML fuera del ciclo: adentro asignan, al final una escritura masiva.
Josu lo ha visto olvidado mil veces, porque el Flow da la sensación de que está todo bien. Después está la trampa del subflow: sacan DML y queries del Flow principal y declaran victoria.
Cuando abren el Flow Reference, el subflow vuelve a consultar y a actualizar por cada iteración. En un cliente grande, un subflow anidado hizo DML en una carga masiva de cuentas: nadie tocó nada, creció el volumen y el provisorio se hizo visible.
Un edificio de departamentos (por qué existen los límites)
Roberto preguntó lo que mucha gente intuye mal: si Salesforce es la nube, ¿por qué consume CPU si parece eterno?
Josu armó la analogía que se queda. Piensen Salesforce y la nube como un edificio de departamentos.
Cada org es un departamento. Comparten agua, ruido, tuberías, y la empresa A y la empresa B no se ven, pero viven en el mismo edificio.
Para que convivan en paz, Salesforce pone límites. Tiempo de una transacción, cantidad de queries, cantidad de trabajos asíncronos.
Si se pasan, muy probablemente bloquea las transacciones un rato (a veces una hora, a veces 24 horas). No es un capricho: un mal desarrollo de ustedes no puede dejar al vecino afuera.
Fran agregó la letra chica: a veces ese límite de agua se puede ampliar, y se cobra. La obligación del consultor es no molestar al cliente ni a sus vecinos.
Vantegrate es partner actual de Salesforce y de Oracle. Eso no los salva de los governor limits: los límites son de la plataforma, no del logo en la puerta.
IDs tatuados y permisos para todos
En Apex, hardcodear un ID está mal y casi todos lo saben. En Flow, ver un ID pegado adentro es mucho más normal, y después siempre termina mal.
No se pueden confiar en que el sandbox y producción tengan los mismos IDs. Si borran el registro, dependen 100% de ese pegote.
En un proyecto de logística (transporte marítimo, sin nombrar la empresa) los IDs estaban tatuados. Una colección de hacía años decía "esto es provisorio, después lo arreglamos".
Aparecieron más Flows, da pereza refactorizarlos y el hardcodeo se propaga. Ruiz, en el chat, lo dijo limpio: usen metadata, no un ID elegante.
Juliana tiró el otro clásico. Hay que crear el campo Manager, pasarlo a producción, y la rápida es permiso para todos, al layout, y chau.
Ahí pierden el control de quién debería ver o editar ese campo. Un día cae una auditoría: ¿por qué un vendedor ve el límite de crédito de un cliente?
Los Permission Sets y los Permission Set Groups son el camino. El perfil, cada vez más, queda para asociar la licencia.
Fran sumó una micropráctica. El historial de campo nativo les deja auditar hasta 20 campos por objeto (con un upgrade pago, hasta 60).
En campos críticos (número de cuenta bancaria, límite de crédito, precio de costo de un producto) anotan fecha, hora, usuario, valor anterior y valor nuevo. Y se puede armar un reporte de auditoría.
Josu frenó el entusiasmo: auditar por auditar llena el storage. A nadie le importa que el contacto pasó de Juan a Juancho; quizá sí les importa que cambió el documento.
Esa es seguridad de verdad. No es prender todos los checks: es decidir qué vale la pena guardar.
Storage: cada registro pesa lo mismo
Otro ejemplo, de no hace mucho. Cuentas personales y promociones para asignarles.
Lo cotidiano es crear un objeto join (promo-cuenta). Técnicamente tiene sentido, hasta que preguntan los números.
¿Cuántas promos? Como mucho 20.
¿Cuántas cuentas? En el caso real había millones, y todas las promos eran para todas las cuentas.
Un millón de cuentas por 20 promos son 20 millones de registros de join, después mandados por API a otro sistema. El modelo "correcto" en el pizarrón ahoga la org.
En consumo masivo esa tentación aparece todo el tiempo. Cumplir por cumplir no alcanza: hay que preguntar para qué quieren esa tabla.
La propuesta de evolución fue otra. Niveles en cuentas y niveles en promos: si la cuenta es nivel 1, traigan las promos de nivel 1.
No asignen el cruce hasta que importe saber si ese cliente usó esa promo. Recién ahí crean el registro.
Hay que conocer la plataforma. En Salesforce cada registro ocupa más o menos lo mismo, tengan un campo o cincuenta.
Fran lo precisó: 2K por registro. El espacio predeterminado de una org, hace más de una década, era 1 giga; la presión de los usuarios lo llevó a 10 gigas (unos 5 millones de registros).
Salesforce les deja ver cuánto ocupa cada objeto. A Josu lo llamó más de un cliente: la plataforma quiere venderle almacenamiento porque está a tope.
Muchas veces el villano no es el objeto de negocio. Email Message: alguien dijo que estaría bueno tener todos los mails en Salesforce.
Nadie los lee ni hace un análisis. Se puede limpiar.
Otro cliente quería la foto de perfil de cada cliente en la pantalla, y eso se comió el file storage. Era solo para ver la cara.
Decisiones chiquitas de "quedaría lindo" amenazan la economía. Si están pagando storage de más, miren precios con el mapa de objetos abierto, no con la factura cerrada.
Borrar casos para ahorrar (y el mes que se comieron)
Salesforce tiene export de data para backup. Eligen objetos y les arma archivos comprimidos con CSV.
La recomendación es ser conscientes cuando van a borrar. Un cliente pidió eliminar todos los casos porque no daba más el storage y necesitaba seguir creando.
Backup listo, delete de veinte minutos. Dos semanas después, un manager (era de Chile) pidió volver a subir el historial.
Tuvieron que inventar External ID, un record type de casos viejos, y se comieron un mes restaurando. El delete fue barato; la restauración, no.
¿Y la papelera? En aquella época, o ya habían pasado los 90 días, o Salesforce cobraba por restaurar, así que re-subieron.
La buena práctica de Fran es de sangre. Cada vez que les pidan tocar data de producción, tiene que estar firmado (un correo de quien lo pide, con todas las garantías).
Si pueden dar la herramienta para que lo haga el negocio, mejor. Si lo hacen ustedes, cúbranse: un error ahí no es un ticket chico.
Archivar sin inflar la org
Mariana preguntó por prácticas para archivar información vieja de forma automática. Desti armó el mapa.
Si quieren guardar millones de registros adentro de Salesforce, existen los Big Objects. Es otra licencia, y la contra es dura: no pueden automatizar con Flow ni con trigger.
Si no quieren pagarle más storage a la plataforma, sale una base externa (un Amazon, un MongoDB). Export programado, archivo, carga afuera.
Después conectan External Objects: se ven como objetos de Salesforce, pero la base no vive ahí. También es una característica paga.
Fran aclaró el uso pensado. External Objects brillan para integrar un ERP (el ejemplo de la clase fue SAP) y exponer parte de esa base adentro de Salesforce.
Ahí sí pueden automatizar como un objeto normal. El precio, dijeron, puede ser elevado: hay que medir el caso.
Otra práctica: objetos de consolidación. Si tienen una montaña de oportunidades viejas, dejan las de los últimos años y resumen el resto.
Un proceso recorre las oportunidades de una cuenta en un mes y crea un registro con la totalización. Doce registros por año, por cliente, en lugar de miles: gobierna el tamaño porque cada registro pesa lo mismo.
Cuando ya pincha: Log Analyzer y Scale Center
Si ya están en una org con muchos Flows y triggers, y pincha por time limit, Josu tiene un miedo favorito. El CPU Time Limit.
Hay una herramienta para Visual Studio Code que arma un call tree a partir del log. Les dice cuántas queries tiró, cuántos registros devolvió, cuánto CPU ocupa cada cosa.
Se llama Log Analyzer y, cuando pincha, les pone una línea roja en el error. Para el equipo de Salesforce developers no es un lujo: es linterna.
Desti mostró otra pantalla para ver coverage de tests sin meterse en la Developer Console. Y después, el Scale Center: hay que hablar con un representante para que lo habiliten.
Sirve para dejar de discutir una sensación. "La org está lenta a las tres de la tarde" pasa a ser un ensayo medido (horario pico, un Flow, un batch, un set de datos de prueba) con métricas de segundos reales.
Eduardo preguntó si se lo habilitan gratis. Desti cree que sí: hay que hablar con ventas.
Hacerlo bien de una
El desafío de la clase no era memorizar un número de límite. Era cortar la bola de nieve antes de que el usuario vea el error.
Ante la duda, reduzcan el escenario, saquen el DML del loop, no hardcodeen IDs, no creen 20 millones de registros porque el modelo da. El "después lo arreglo" no es un plan.
El equipo está armando una guía de estándares de desarrollo (unas 38 páginas) que mezcla el universo de Apex y de Flow. No existe lista así, dijeron, ni en la documentación oficial.
El objetivo es doble: estandarizar lo que construyen y dárselo de comer a un Cursor o a un Antigravity (nomenclatura, nodos de Flow, no meter DML dentro de un for). Lo van a compartir también como prompt para Gemini, ChatGPT o Claude.
Eso conecta con los agentes de IA. El agente no perdona un Flow mal pensado: lo replica más rápido.
Estas masterclass de los jueves quedan en Pulse. Si quieren bajar esto a su org (entry conditions, bulkificación, storage y un Scale Center que deje de ser una corazonada), pidan una demo.
La clase de enero no mostró cada pantalla de Setup. Mostró el mapa: requerimiento chiquito, límites del edificio, y la disciplina de hacerlo bien de una.
Eso es rendimiento. El resto es un Flow que anda.















