To avoid exceeding the flex queue limit, we would like to chain a batchable, but change the User that the batchable runs under for each new batchable so that its updates are tied to the correct User i.e. so the "Last Modified By" is correct.

In 2014 there was no way to do this - see Can you run a Batchable Apex bulk update as a different user? - and AFAIK there is still now way to do this. Is there?

  • Would it always be a specific user, or the user would need to be dynamic? – sfdcfox Jun 19 '18 at 14:28
  • @sfdcfox The User would need to be dynamic. Essentially it is async processing of an event queue where (ideally) the User who created the event should be used to process the event. – Keith C Jun 19 '18 at 16:33
  • an imperfect solution would be to write a platform event at finish() and then consume in a trigger wherein the running user is AutomatedProcess – cropredy Jun 19 '18 at 19:05
  • @cropredy Interesting approach to switching out of a specific User into a generic User. – Keith C Jun 19 '18 at 21:49

What you probably want is to Give the Administrator the ability to make "ghost" updates, but we've been waiting a decade for that idea. Technically, with Named Credentials, you could impersonate a user in an API call, but they'd have to basically give you their username and password.

If you were really serious about it, and it had to be done, you could write a Connected App, have the user grant access (with Offline Access) to that Connected App, capture the Refresh Token, then you can do all sorts of things with that Refresh Token using API calls, such as an Execute Anonymous script to kick off the additional queueable calls, etc.

Note that this method is a Bad Idea. In fact, it's a Very Bad Idea. Anyone who figures out how to get to the Refresh Tokens could impersonate any user in your system. You'd have to take special care to keep the data encrypted and not leak it in debug logs, etc. All of that work just to let someone impersonate someone else isn't something I'd consider lightly.

For now, you'll probably just want to accept that the Last Modified audit fields will show what they're intended to show. You might want to raise awareness for the Idea mentioned in the first paragraph.


This is the world's Ugliest solution.

Your original batch code is just the same, you have to make an alteration in your finish method.

global class MyBatch implements Database.Batchable<sObject>, Database.AllowsCallouts{

    global Database.QueryLocator start(Database.BatchableContext BC){

    global void execute(Database.BatchableContext BC, List<sObject> scope){


    global void finish(Database.BatchableContext BC){
            //Now instead of adding a new Batch Job with same running user we would do something funny.

        String newUserSessionId = MyBatch.getSessionIdForNewUser(); //U can use Named Credentialss as well
        MyBatch.executeAnon(newUserSessionId); // This will be replicating calling executeAnon rest endpoint with the sessionId retrieved. Magic happens here

    private String getSessionIdForNewUser(){
        //Use Oauth2 Username password flow to get SessionID using HTTP callouts. Can store username and password in custom setting/metadata whatever suits
        return sessionId;

    private static void executeAnon(String sessionId){

        Http http = new HTTP();
        HttpRequest httpRequest = new HttpRequest();
        httpRequest.setEndPoint(URL.getSalesforceBaseUrl().toExternalForm() + '/services/data/v40.0/tooling/executeAnonymous?anonymousBody=Database.executeBatch(new MyBatch());');
        httpRequest.setHeader('Authorization', 'Bearer ' + sessionId);// We will use session id from anothe rest call
        HttpResponse httpResp = http.send(httpRequest);

        System.debug(httpResp.getBody() + httpResp.getStatusCode());
        return calloutSccuess;
  • Pranay, thanks for sharing this. If I get desperate... – Keith C Sep 7 '18 at 18:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.