Azure y cloud

Azure Functions vs API tradicional: cuándo usar cada una

Azure Functions parece más barato que una API en App Service hasta que aparecen arranques en frío, límites de tiempo y lógica repartida. Cómo decidir.

Por Leyton Manuel Espitia Diaz 5 min de lectura

Fragmento de código C# de una Azure Function con disparador de cola de Service Bus

Las Azure Functions se presentan con una promesa atractiva: escribes solo la función, Azure se encarga de escalarla y pagas únicamente por las ejecuciones. Para muchos casos es exactamente así. Para otros, la promesa se vuelve una API partida en cuarenta funciones, con arranques en frío en el primer clic de la mañana y una factura difícil de predecir.

La pregunta útil no es si Functions es mejor que una API tradicional, sino qué forma tiene la carga de trabajo.

Dónde Functions encaja muy bien

Trabajo disparado por eventos

Es su mejor caso. Algo ocurre y hay que reaccionar:

public class OrderCreatedFunction(ILogger<OrderCreatedFunction> logger, IInvoiceService invoices)
{
    [Function(nameof(OrderCreatedFunction))]
    public async Task Run(
        [ServiceBusTrigger("orders-created", Connection = "ServiceBus")] OrderCreatedMessage message,
        CancellationToken ct)
    {
        logger.LogInformation("Generando factura del pedido {OrderId}", message.OrderId);
        await invoices.GenerateAsync(message.OrderId, ct);
    }
}

Un mensaje en una cola, un archivo subido a Blob Storage, un cambio en Cosmos DB. La función escala con la cantidad de eventos y no consume nada cuando no hay.

Tareas programadas

[Function("NightlyCleanup")]
public async Task Run([TimerTrigger("0 0 3 * * *")] TimerInfo timer, CancellationToken ct) { ... }

Un proceso que corre a las 3 a. m. no necesita un servidor encendido las otras 23 horas.

Cargas muy variables o esporádicas

Un webhook que recibe mil llamadas en un minuto y ninguna el resto del día. Un proceso que solo corre a fin de mes.

Dónde una API tradicional suele ser mejor

APIs con tráfico constante y latencia importante

En el plan de consumo, una función inactiva se descarga. La siguiente petición paga el arranque en frío: cargar el proceso, el runtime de .NET y tus dependencias. Puede ser desde unos cientos de milisegundos hasta varios segundos. Para un webhook da igual; para la API que usa tu aplicación móvil, el usuario lo nota.

El plan Flex Consumption y el plan Premium permiten instancias siempre listas que reducen ese problema, pero tienen un costo fijo, y ahí la diferencia de precio con un App Service se reduce mucho.

Muchos endpoints que comparten lógica y estado

Una API con 60 endpoints, autenticación, validación, middleware y versionado es exactamente para lo que existe ASP.NET Core. Llevarla a Functions significa repartir esa lógica en funciones HTTP y reconstruir lo que el pipeline de ASP.NET Core ya da (aunque el modelo aislado de Functions admite parte de la integración con ASP.NET Core).

Procesos largos

En el plan de consumo, una ejecución tiene un tiempo máximo (por defecto 5 minutos, configurable hasta 10). Para procesos más largos hay que usar otros planes, partir el trabajo o usar Durable Functions, que agregan su propio modelo de programación.

Conexiones a la base de datos

Una API mantiene un pool de conexiones estable. Cuando Functions escala a decenas de instancias por un pico de mensajes, cada una abre sus propias conexiones y la base de datos puede quedarse sin ellas. Hay que limitar la concurrencia (por ejemplo, maxConcurrentCalls en el disparador de Service Bus o un máximo de instancias) para proteger a los sistemas que están detrás.

El modelo actual: worker aislado

Si empiezas hoy con .NET, el modelo es el worker aislado (isolated worker): la función corre en su propio proceso, con su propia versión de .NET, inyección de dependencias y middleware. El modelo in-process deja de tener soporte en noviembre de 2026, así que los proyectos que lo usan deberían estar migrando.

var builder = FunctionsApplication.CreateBuilder(args);

builder.Services.AddScoped<IInvoiceService, InvoiceService>();
builder.Services.AddDbContext<AppDbContext>(o => o.UseSqlServer(builder.Configuration.GetConnectionString("Sql")));

builder.Build().Run();

Una combinación que funciona bien

En muchas arquitecturas, la respuesta no es una u otra sino las dos:

Aplicación móvil / web
        │
        ▼
API en App Service (ASP.NET Core)  ──► publica "pedido creado" en Service Bus
                                               │
                                               ▼
                                 Azure Functions: factura, correo, inventario

La API atiende a los usuarios con latencia baja y estable. Las funciones hacen el trabajo asíncrono, escalan con los eventos y no hacen esperar al usuario.

El trade-off

Azure Functions (consumo) API en App Service
Costo con poco tráfico Casi cero Costo fijo del plan
Costo con tráfico constante alto Puede superar al fijo Predecible
Latencia del primer request Arranque en frío Estable
Escalado Automático por eventos Reglas de escalado
Procesos largos Limitados Sin límite propio
Estructura para APIs grandes Fragmentada Natural

Cuándo no usar Functions

  • Como reemplazo directo de una API con tráfico constante y requisitos de latencia.
  • Cuando la lógica de negocio queda repartida en decenas de funciones que se llaman entre sí por HTTP.
  • Cuando no puedes limitar cuánto escala y los sistemas detrás (base de datos, APIs de terceros) tienen capacidad limitada.

Conclusión

Functions es excelente para reaccionar a eventos, ejecutar tareas programadas y absorber cargas esporádicas. Una API tradicional sigue siendo la mejor opción para atender usuarios con tráfico constante. La mayoría de sistemas que funcionan bien en Azure usan las dos, cada una para lo suyo. Y cuando la API y las funciones comparten una base de datos, revisa cómo se comportan los niveles de aislamiento bajo esa concurrencia.

Leyton Manuel Espitia Diaz

Escrito por

Leyton Manuel Espitia Diaz

CEO y fundador de Nakanaba

Desarrollador de software y fundador de Nakanaba. Lidera la arquitectura de Vitrin: backend en .NET, aplicaciones en Angular y .NET MAUI, SQL Server y servicios en Cloudflare.

Lleva tu aplicación a la nube con criterio

Diseñamos arquitecturas en Azure que crecen con tu negocio sin disparar los costos de infraestructura.

Ver soluciones escalables