Invoke AWS Lambda function only once, at a single specified future time
Solution 1
You can schedule lambda event using following syntax:
cron(Minutes Hours Day-of-month Month Day-of-week Year)
Note: All fields are required and time zone is UTC only
Please refer this AWS Documentation for Details.
Thanks
Solution 2
You can use DynamoDB TTL
feature to implement this easily, simply do the following:
1- Put item with TTL
, the exact time you want to execute or invoke a lambda function.
2- Configure DynamoDB Streams
to trigger a lambda function on item's remove
event.
Once the item/record is about to expire, your lambda will be invoked. you don't have to delete or cleanup anything as the item in dynamodb is already gone.
NOTE: However the approach is easy to implement and scales very well, but there's one precaution to mention; using DynamoDB TTL
as a scheduling mechanism cannot guarantee exact time precision as there might be a delay. The scheduled tasks are executed couple of minutes behind.
Solution 3
You can schedule a step function which can wait until a specific point in time before invoking the lambda with an arbitrary payload.
https://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-wait-state.html
Something like this
const stepFunctions = new AWS.StepFunctions()
const payload = {
stateMachineArn: process.env.SCHEDULED_LAMBDA_SF_ARN,
name: `${base64.encode(email)}-${base64.encode(timestamp)}`, // Dedupe key
input: JSON.stringify({
timestamp,
lambdaName: 'myLambdaName',
lambdaPayload: {
email,
initiatedBy
},
}),
}
await stepFunctions.startExecution(payload).promise()
Solution 4
I understand its quite late to answer this question. But anyone who wants to use CRON expression to trigger an event(or call an API) only once can use following example:
This event will be triggered only once on January 1, 2025 - 12:00:00 GMT
00 12 01 01 ? 2025
For those who do not have much knowledge of cron syntax:
Minutes Hours DayOfMonth Month DayOfWeek Year
I am using this with AWS Cloudwatch Events and the result looks like this:
Note: I did not have to specify Day of week, since I have given it a fixed date and thats obvious.
Related videos on Youtube
Ethan Harlig
Updated on June 18, 2022Comments
-
Ethan Harlig almost 2 years
I want to be able to set a time to invoke an AWS Lambda function, then have that function be invoked then and only then. For example, I want my Lambda function to run at 9:00pm on December 19th, 2017. I don't want it to repeat, I don't want it to invoke now, just at 9:00pm on the 19th.
I understand that CloudWatch provides Scheduled Events, and I was thinking that when a time to schedule this reminder for is inputted, a CloudWatch Scheduled Events is created to fire in that amount of time from now (so like if you schedule it at 8:22pm to run at 9pm, it’ll be 38 mins), then it invokes the Lambda function at 9pm which then deletes the CloudWatch Scheduled Event. My issue with this is that when a CloudWatch Scheduled Event is created, it executes right then, then at the specified interval.
Any other ideas would be appreciated, as I can't think of another solution. Thanks in advance!
-
Ethan Harlig over 6 yearsMaybe I am misunderstanding the documentation, but it seems like all of the examples given for cron expressions are repetitive events. Per their examples, it doesn't seem like I want to use that to invoke a Lambda function once at a given time.
-
RredCat over 6 years@EthanHarlig You misunderstand documentation. It is possible to setup cron for repetitive and one time events both. You have to specify year, month, day of month, hour and minutes for your task.
-
Ethan Harlig over 6 years@RredCat I see! So if I wanted to invoke a Lambda at 12:00pm on December 20th (UTC), I would use
cron(0 12 20 12 * 2017)
and that would specify that it is 12:00, on December 20, 2017, and it doesn't matter what day of week that is? -
Kush Vyas over 6 years@EthanHarlig I agree with RredCat , you can set it up one time and on repeat also.
-
AC88 about 6 years~~This doesn't seem to work for me? Trying to set UTC 03:20 (about 4 minutes from now):
aws events put-rule --name testing-trigger --schedule-expression 'cron(0 20 3 26 2 ? 2018)'
->An error occurred (ValidationException) when calling the PutRule operation: Parameter ScheduleExpression is not valid.
~~ Oops, never mind, starts with minutes, not seconds. -
madhead over 5 yearsNote that CloudWatch does not guarantee exactly once firing. This guy sent emails twice and I'm seeing duplicated data in my croned reports. Because "In rare cases, the same rule can be triggered more than once for a single event or scheduled time, or the same target can be invoked more than once for a given triggered rule". But I want to admit that I see at least one doubled shot every 2 days of 3 for 7 scheduled tasks.
-
Blundell about 5 years@madhead you could have your lambda write to a DB field when it it triggered, so if it is triggered twice the second one knows not to execute
-
Gergely M almost 5 yearsSpot on, thanks! Let me emphasize one thing that caused this error to me (see the notes at the end of the page linked above ): "One of the day-of-month or day-of-week values must be a question mark (?)."
-
Samantha Atkins over 4 yearsIt seems fundamentally wrong to involve dynamodb and all these considerations for something by its nature so simple.
-
RNA about 4 yearsyou are genius!
-
Gordon Leigh about 4 yearsSo long as you're ok with it actually taking up to 48 hours. According to the docs: "DynamoDB typically deletes expired items within 48 hours of expiration. The exact duration within which an item truly gets deleted after expiration is specific to the nature of the workload and the size of the table. Items that have expired and have not been deleted still appear in reads, queries, and scans. These items can still be updated, and successful updates to change or remove the expiration attribute are honored."
-
U.Rush about 4 years
-
Thayne about 4 yearsThe documentation isn't clear, if a schedule can never trigger again, is it automatically cleaned up?
-
M Faisal Hameed over 3 yearsExcellent, thanks for the idea. This is exactly what I was looking for.
-
freethebees about 3 yearsThis is a really intriguing method. I really like that this would give the ability to pass arguments to the Lambda function too, unlike a cron execution. It's worth considering, however, deleting an item manually will also trigger the event. So you'll want to check the ExpirationTime in your Lambda.
-
Lukas Liesis about 3 yearskeep in mind that you can create only 100 rules per account. There is option to ask support to increase this limit, but seems like this is not designed to be used for high scale. Anyone knows someone who uses like 100k such rules on single account?