I understand that when I perform a Database.delete() operation, records will end up in my org's recycle bin. And their presence in the recycle bin is reflected by the IsDeleted field on the object.

But if those records are (for example) scrapes of a web page, they are of little interest to users and I don't want them kicking around in the org. Currently the only way I can see to 'hide' them would be to misuse a Protected (List) Custom Setting object.

From Apex, how can I delete a record and skip this, so it doesn't clutter a user's recycle bin?


Take a look at the Database.emptyRecycleBin(obj) method or the other variants in the Database class such as Database.emptyRecycleBin(listOfSObjects)

For example, to permanently delete a contact with Id of '003i000000O4xYZ' in the recycle bin:

Contact c = new Contact(Id = '003i000000O4XyZ');
  • 2
    Just nipped me to the post on this one Peter! ;-) Also note that there is a couple of other variants of this method. One which takes a list of Id's as well. Dec 23 '13 at 13:34
  • 3
    Good point. Updated the answer. Being on xmas vacation I don't have my actual work to get in the way of important things like tending to the SFSE. ;) Dec 23 '13 at 13:39
  • Thanks a lot for the answer, Peter Knolle, it was quite useful. I think the links in the answer are not working any more, though, I am receiving a 404 Not Found error. I guess it was referencing Apex Developer's Guide, so it was quite easy to find the related entry there. Jun 24 '14 at 8:07
  • @JesusArcasFinancialForce - Thanks. I updated the answer with fixed links. Jun 24 '14 at 14:16
  • And I updated the links again. Dammit, Salesforce, stop breaking the internet. Jun 7 '18 at 20:11

It is possible to hard delete using DataBase.emptyRecycleBin method in the Batch class. Create a sample Batch class as mentioned below and use DataBase.emptyRecycleBin method in the Batch class.

global class BatchDeletion implements Database.Batchable<sObject>, Schedulable{   
    global BatchDeletion(){}

    global Database.QueryLocator start(Database.BatchableContext bc){
        return Database.getQueryLocator([Select id from Account where Name='Test Account12']);

    //Execute method for the Schedulable interface
    global void execute(SchedulableContext sc){   
        //execute the batch
        BatchDeletion deleteCS = new BatchDeletion();
        ID batchprocessid = Database.executeBatch(deleteCS);

    //Execute method for the batchable interface
    global void execute(Database.BatchableContext BC, list<sObject> scope){     
        delete scope;   

    global void finish(Database.BatchableContext BC){}

Note: 1. The DML operation datatbase.emptyRecycleBin is limited to 200 items, it is a known issue and currently no workaround is possible for this. http://success.salesforce.com/issues_view?id=a1p30000000STLXAA4

  • 2
    Thanks for this example. Never dawned on me that you could combine the schedulable and batchable interfaces in one class like you have done here. Also, thanks for the emptyRecycleBin example. Upvoted. Dec 30 '14 at 21:53

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.