I've been experimenting with AWS AppSync and I'm intrigued by the idea of ditching VTL entirely in favour of Direct Lambda Resolvers. Ignoring the monetary cost aspect which Lambda adds, my biggest question was the performance impact this might have. So, I ended up doing some basic real world tests.
A direct lambda resolver for the field
Query.getNote and a VTL DynamoDB resolver for
Query.ddbGetNote. Both versions are performing a
GetItem operation on the same DynamoDB table.
The first try with a Lambda function mostly in AWS CDK default configuration (i.e. 128 MB Ram) was quite disappointing.
The (warm) Lambda resolver took ~ 200 ms compared to 14 ms of the VTL DynamoDB call. Interestingly enough, most time consuming in the Lambda function appears to be the DynamoDB call. This seems odd.
A bit of research suggested, that this is an issue for underpowered Lambda functions. I've found this slide deck with a nice chart for balancing performance / costs for DynamoDB calls in Lambda functions.
The sweet spot seems to be around 512 MB memory for a Lambda function.
I changed the Lambda function to 512 MB and left everything else as it was. And surprise, surprise - This looks way better now.
Now the (warm) Lambda resolver takes ~ 30 ms compared to still 14 ms of the VTL DynamoDB call.
Skipping VTL in favour of direct Lambda resolvers seems to be reasonable for the gained flexibility, even though there are a few drawbacks. There's a bit of an overhead to call the Lambda function, which gets drastically worse on cold starts (+ ~ 600 ms).
In terms of costs, 1 million invocations at 100 ms with 512 MB would clock in at roughly 1 USD. That's on top of the 4 USD per million operations in AppSync. All in all, not exactly cheap in scale but nothing I'd be concerned about for now. That's something to optimize when costs would become an issue.
I'll continue to explore Direct Lambda Resolvers for all cases and report how it goes :)