4.6.x node.module node_delete($edit)
4.7.x node.module node_delete($nid)
5.x node.module node_delete($nid)
6.x node.module node_delete($nid)
7.x node.module node_delete($nid)

Delete a node.

3 calls to node_delete()
blogapi_blogger_delete_post in modules/blogapi/blogapi.module
Blogging API callback. Removes the specified blog node.
node_delete_confirm_submit in modules/node/node.pages.inc
Execute node deletion
node_multiple_delete_confirm_submit in modules/node/node.admin.inc


modules/node/node.module, line 974
The core that allows content to be submitted to the site. Modules and scripts may programmatically submit nodes using the usual form API pattern.


function node_delete($nid) {

  // Clear the cache before the load, so if multiple nodes are deleted, the
  // memory will not fill up with nodes (possibly) already removed.
  $node = node_load($nid, NULL, TRUE);
  if (node_access('delete', $node)) {
    db_query('DELETE FROM {node} WHERE nid = %d', $node->nid);
    db_query('DELETE FROM {node_revisions} WHERE nid = %d', $node->nid);
    db_query('DELETE FROM {node_access} WHERE nid = %d', $node->nid);

    // Call the node-specific callback (if any):
    node_invoke($node, 'delete');
    node_invoke_nodeapi($node, 'delete');

    // Clear the page and block caches.

    // Remove this node from the search index if needed.
    if (function_exists('search_wipe')) {
      search_wipe($node->nid, 'node');
    watchdog('content', '@type: deleted %title.', array(
      '@type' => $node->type,
      '%title' => $node->title,
    drupal_set_message(t('@type %title has been deleted.', array(
      '@type' => node_get_types('name', $node),
      '%title' => $node->title,


Garrett Albright’s picture

Note that node_delete() calls node_load(), which keeps a cache of loaded nodes. That means it's possible to load a node with node_load() which should have been explicitly deleted with node_delete() earlier in the session! In other words, this works:

$node = node_load($nid);

There are performance implications to this, and possibly security ones as well. See the node_load() documentation and its comments for information on how to clear node_load()'s cache. Also see this issue in Drupal's issue queue.

akalata’s picture

The core issue mentioned above was fixed in early 2010.

hefox’s picture

Note that node_delete calls node_access check so cannot be used in some occasions, like when running cron with an anon user.

Or, say, trying to delete a node as anon with drush php-eval "node_delete(nid) ;", however drush php-eval "global \$user; \$user = user_load(1);node_delete(nid) ;" works

heydemo’s picture

For security, it's a good practice to restore $user to original state - e.g.

global $user;
$original_user = $user;
$user = user_load(1);
$user = $original_user;
sanduhrs’s picture

There is official documentation on how to do that.
On that page the afore mentioned method has been explicitly declared unsafe.
See Safely Impersonating Another User

snehalK’s picture

I have deleted unwanted node from database still displaying in a block. I have also cleared cache. How to remove it from display?
Please suggest.

mayur.pimple’s picture

After delete your node from database then use drupal_goto